1、图片缩放:不解析整个图片信息。

public class DemoActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ImageView iv = (ImageView) this.findViewById(R.id.iv);
// BitmapFactory.Options bmpFactoryOptions = new BitmapFactory.Options();
// //按1/8的大小加载到内存
// bmpFactoryOptions.inSampleSize = 8;
// Bitmap bm = BitmapFactory.decodeFile("/sdcard/img.jpg",bmpFactoryOptions);
// iv.setImageBitmap(bm); //
//1. 首先得到屏幕的宽高
Display currentDisplay = getWindowManager().getDefaultDisplay();
int dw = currentDisplay.getWidth();
int dh = currentDisplay.getHeight();
// 2. 获取图片的宽度和高度
BitmapFactory.Options bmpFactoryOptions = new BitmapFactory.Options();
// 设置inJustDecodeBounds = true ,只会解析文件头信息;
bmpFactoryOptions.inJustDecodeBounds = true;
// 不会真正的解析这个位图
Bitmap bmp = BitmapFactory.decodeFile("/sdcard/img.jpg", bmpFactoryOptions);
//得到图片的宽度和高度
int heightRatio = (int)Math.ceil(bmpFactoryOptions.outHeight/(float)dh);
int widthRatio = (int)Math.ceil(bmpFactoryOptions.outWidth/(float)dw);
Log.v("HEIGHTRATIO",""+heightRatio);
Log.v("WIDTHRATIO",""+widthRatio); //真正的解析位图
bmpFactoryOptions.inJustDecodeBounds = false; if(heightRatio>widthRatio){
bmpFactoryOptions.inSampleSize = heightRatio;
}else{
bmpFactoryOptions.inSampleSize = widthRatio;
}
bmp = BitmapFactory.decodeFile("/sdcard/img.jpg", bmpFactoryOptions); iv.setImageBitmap(bmp);
}
}

  2、ExifInterface获取或设置图片的exif信息:

public class DemoActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main); try {
ExifInterface exif = new ExifInterface("sdcard/img.jpg");
System.out.println( exif.getAttribute(ExifInterface.TAG_DATETIME));
System.out.println( exif.getAttribute(ExifInterface.TAG_IMAGE_LENGTH));
System.out.println( exif.getAttribute(ExifInterface.TAG_IMAGE_WIDTH));
exif.setAttribute("camera", "柯达相机");
System.out.println( exif.getAttribute("camera"));
} catch (Exception e) {
e.printStackTrace();
} }
}

3、从图库里面选择一个图片,然后将它设置到ImageView。

public class DemoActivity extends Activity {
ImageView iv;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
iv = (ImageView) this.findViewById(R.id.iv);
} public void click(View view){
//选择图库意图,打开图库
Intent intent = new Intent(Intent.ACTION_PICK);
intent.setType("image/*");
startActivityForResult(intent, 0);
} @Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if(data!=null){
//图片的uri
Uri uri = data.getData() ;
iv.setImageURI(uri);
}
super.onActivityResult(requestCode, resultCode, data);
}
}

  4、创建图片(bitmap)的拷贝:

public class DemoActivity extends Activity{
ImageView iv1;
ImageView iv2;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
iv1= (ImageView) this.findViewById(R.id.iv1);
iv2= (ImageView) this.findViewById(R.id.iv2);
} public void click(View view){
Intent intent = new Intent(Intent.ACTION_PICK);
intent.setType("image/*");
startActivityForResult(intent, 0);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if(data!=null){
//图片的uri
Uri uri = data.getData() ;
iv1.setImageURI(uri);
// 获取第一个图片 的拷贝 设置到iv2的控件里面
try {
//通过uri获取一个流对象。getContentResolver().openInputStream(uri)
Bitmap bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(uri));
//图片缩放
Matrix matrix = new Matrix();
// matrix.setValues(new float[] {
// 2, 0, 0,
// 0, 1, 0,
// 0, 0, 1
// });//矩阵缩放
// matrix.setScale(1.5f, 1.0f);//水平方向为1.5倍,垂直方向不做改变
// matrix.postTranslate(bitmap.getWidth(), 1.0f);//与setScale可以实现图片翻转
// matrix.setRotate(30);
//画笔
Paint paint = new Paint();
paint.setAntiAlias(true);//消除锯齿
matrix.setRotate(15);//图片旋转
//得到一个大小 配置跟原图一样的空白的位图
//Bitmap alterbitmap = Bitmap.createBitmap(bitmap.getWidth()*2, bitmap.getHeight(), bitmap.getConfig());
Bitmap alteredBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(),
matrix, false);
//画布对象
Canvas canvas = new Canvas();
//将图片流bitmap应用到画布上
canvas.drawBitmap(bitmap, matrix, paint);
iv2.setImageBitmap(alteredBitmap);
} catch (Exception e) {
e.printStackTrace();
}
}
super.onActivityResult(requestCode, resultCode, data);
}
}

最后一个:filter解释
true if the source should be filtered. Only applies if the matrix contains more than just translation.
当进行的不只是平移变换时,filter参数为true可以进行滤波处理,有助于改善新图像质量;flase时,计算机不做过滤处理。

图片裁剪,可用这个方法:
Bitmap source:要从中截图的原始位图
int x: 起始x坐标
int y:起始y坐标
int width: 要截的图的宽度
int height:要截的图的高度

要想imageView.setImageMatrix()方法起作用,xml得配置android:scaleType="matrix"

matrix.setRotate和matrix.postRotate的区别:
post...:平移、旋转等效果可以叠加在一起;
set...:前一种效果会消失,只有后来的操作,即它会重置Matrix

 

 5、图片合成:

public class DemoActivity extends Activity {
Bitmap basebitmap;
Canvas canvas ;
Paint paint;
ImageView iv;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
iv = (ImageView) this.findViewById(R.id.iv);
}
public void select1(View view){
Intent intent = new Intent(Intent.ACTION_PICK);
intent.setType("image/*");
startActivityForResult(intent, 10);
// 从图库里面获取第一个图片
}
public void save(View view){
File file = new File("/sdcard/1.jpg");
FileOutputStream fos;
try {
fos = new FileOutputStream(file);
basebitmap.compress(CompressFormat.JPEG, 100, fos);
//显示的发送一条广播
//sd卡挂载的广播
Intent intent = new Intent(Intent.ACTION_MEDIA_MOUNTED,Uri.parse("file://"+Environment.getExternalStorageDirectory()));
sendBroadcast(intent);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
} public void select2(View view){
Intent intent = new Intent(Intent.ACTION_PICK);
intent.setType("image/*");
startActivityForResult(intent, 20);
// 从图库里面获取第一个图片
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if(requestCode==10){
if(data!=null){
Uri uri = data.getData();
try {
Bitmap bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(uri)); basebitmap = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), bitmap.getConfig());
canvas = new Canvas(basebitmap);
paint = new Paint();
canvas.drawBitmap(bitmap, 0, 0, paint); } catch (Exception e) {
e.printStackTrace();
}
}
}else if(requestCode==20){
if(data!=null){
Uri uri = data.getData();
//把第二张位图的内容 画在 basebitmap上
try {
Bitmap bitmap = BitmapFactory.decodeStream( getContentResolver().openInputStream(uri));
paint.setXfermode(new PorterDuffXfermode(android.graphics.PorterDuff.Mode.MULTIPLY));
canvas.drawBitmap(bitmap, 0,0, paint);
iv.setImageBitmap(basebitmap);
} catch (Exception e) {
e.printStackTrace();
} }
}
super.onActivityResult(requestCode, resultCode, data);
}
}

  6、根据路径Path绘制文字:

public class DemoActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new MyView(this));
}
private class MyView extends View{
public MyView(Context context) {
super(context);
}
@Override
protected void onDraw(Canvas canvas) { Paint paint = new Paint();
paint.setColor(Color.GREEN);
paint.setTextSize(20);
paint.setTypeface(Typeface.DEFAULT);
Path p = new Path();
p.moveTo(20, 20);
p.lineTo(100, 150);
p.lineTo(200, 220);
canvas.drawTextOnPath("Hello this is text on a path", p, 0, 0, paint);
super.onDraw(canvas);
}
}
}

  7、绘图(根据手指移动创建图片并保存):

public class DemoActivity extends Activity {
ImageView iv;
Bitmap bitmap;
Canvas canvas;
Paint paint;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
iv = (ImageView) this.findViewById(R.id.iv);
Display diaplay = getWindow().getWindowManager().getDefaultDisplay();
int height = diaplay.getHeight() - 40;
int width = diaplay.getWidth();
bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
iv.setImageBitmap(bitmap);
canvas = new Canvas(bitmap);
paint= new Paint();
paint.setColor(Color.GREEN);
paint.setStrokeWidth(10);
iv.setOnTouchListener(new OnTouchListener() { float startx = 0;
float starty = 0; @Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
startx = event.getX();
starty = event.getY(); break;
case MotionEvent.ACTION_MOVE:
float x = event.getX();
float y = event.getY();
canvas.drawLine(startx, starty, x, y, paint);
startx = event.getX();
starty = event.getY(); //通知imageview更新界面
iv.invalidate();
break;
case MotionEvent.ACTION_UP:
float endx = event.getX();
float endy = event.getY();
canvas.drawLine(startx, starty, endx, endy, paint);
//通知imageview更新界面
iv.invalidate();
break;
default:
break;
} return true;
}
}); } public void save(View view) {
File file = new File("/sdcard/"+System.currentTimeMillis()+".jpg");
FileOutputStream fos;
try {
fos = new FileOutputStream(file); bitmap.compress(CompressFormat.JPEG, 100, fos);
//显示的发送一条广播
//sd卡挂载的广播
Intent intent = new Intent(Intent.ACTION_MEDIA_MOUNTED,Uri.parse("file://"+Environment.getExternalStorageDirectory()));
sendBroadcast(intent); } catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

8、矩阵Matrix

Matrix的操作,总共分为translate(平移),rotate(旋转),scale(缩放)和skew(倾斜)四种,每一种变换在Android的API里都提供了set, post和pre三种操作方式,除了translate,其他三种操作都可以指定中心点。
set是直接设置Matrix的值,每次set一次,整个Matrix的数组都会变掉。
post是后乘,当前的矩阵乘以参数给出的矩阵。可以连续多次使用post,来完成所需的整个变换。

例如,要将一个图片旋转30度,然后平移到(100,100)的地方,那么可以这样做:

Matrix m =  new  Matrix();
m.postRotate(30 );
m.postTranslate(100 , 100 );

pre是前乘,参数给出的矩阵乘以当前的矩阵。所以操作是在当前矩阵的最前面发生的。例如上面的例子,如果用pre的话

Matrix m =  new  Matrix();
m.setTranslate(100 , 100 );
m.preRotate(30 )

旋转、缩放和倾斜都可以围绕一个中心点来进行,如果不指定,默认情况下,是围绕(0,0)点来进行。

public   class  MyView  extends  View {  

    private  Bitmap mBitmap;
private Matrix mMatrix = new Matrix(); public MyView(Context context) {
super (context);
initialize();
} private void initialize() { Bitmap bmp = ((BitmapDrawable)getResources().getDrawable(R.drawable.show)).getBitmap();
mBitmap = bmp;
/*首先,将缩放为100*100。这里scale的参数是比例。有一点要注意,如果直接用100/
bmp.getWidth()的话,会得到0,因为是整型相除,所以必须其中有一个是float型的,直接用100f就好。*/
mMatrix.setScale(100f/bmp.getWidth(), 100f/bmp.getHeight());
//平移到(100,100)处
mMatrix.postTranslate(100 , 100 );
//倾斜x和y轴,以(100,100)为中心。
mMatrix.postSkew(0 .2f, 0 .2f, 100 , 100 );
} @Override protected void onDraw(Canvas canvas) {
// super.onDraw(canvas); //如果界面上还有其他元素需要绘制,只需要将这句话写上就行了。 canvas.drawBitmap(mBitmap, mMatrix, null );
}
}
pre方法表示矩阵前乘,例如:变换矩阵为A,原始矩阵为B,pre方法的含义即是A*B

post方法表示矩阵后乘,例如:变换矩阵为A,原始矩阵为B,post方法的含义即是B*A

matrix.preScale(0.5f, 1);
matrix.preTranslate(10, 0);
matrix.postScale(0.7f, 1);
matrix.postTranslate(15, 0);
等价于: translate(10, 0) -> scale(0.5f, 1) -> scale(0.7f, 1) -> translate(15, 0) 注意:后调用的pre操作先执行,而后调用的post操作则后执行。 set方法一旦调用即会清空之前matrix中的所有变换,例如: matrix.preScale(0.5f, 1);
matrix.setScale(1, 0.6f);
matrix.postScale(0.7f, 1);
matrix.preTranslate(15, 0);
等价于 translate(15, 0) -> scale(1, 0.6f) -> scale(0.7f, 1) matrix.preScale (0.5f, 1)将不起作用。

Android学习笔记_66_图片处理专题的更多相关文章

  1. Android学习笔记之图片轮播...

    PS:一个bug又折腾了一个下午....哎... 学习内容: 1.Android利用ViewPager和PagerAdapter实现图片轮播... 2.使用反射机制获取Android的资源信息... ...

  2. Android学习笔记 ImageSwitcher图片切换组件的使用

    activity_main.xml <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android&qu ...

  3. Android学习笔记_38_图片的拖动、缩放功能和多点触摸

    一.基础知识: 引用 理论上 Android可以处理 多达256 个手指的触摸,大概只有章鱼哥能享受这种技术带来的便利.就编程人员来说,编写多点触摸和单点触摸的方式几乎一模一样.其奥秘在于Motion ...

  4. Android学习笔记进阶之在图片上涂鸦(能清屏)

    Android学习笔记进阶之在图片上涂鸦(能清屏) 2013-11-19 10:52 117人阅读 评论(0) 收藏 举报 HandWritingActivity.java package xiaos ...

  5. 【转】 Pro Android学习笔记(七四):HTTP服务(8):使用后台线程AsyncTask

    目录(?)[-] 5秒超时异常 AsyncTask 实现AsyncTask抽象类 对AsyncTask的调用 在哪里运行 其他重要method 文章转载只能用于非商业性质,且不能带有虚拟货币.积分.注 ...

  6. 【转】 Pro Android学习笔记(七五):HTTP服务(9):DownloadManager

    目录(?)[-] 小例子 保存在哪里下载文件信息设置和读取 查看下载状态和取消下载 文章转载只能用于非商业性质,且不能带有虚拟货币.积分.注册等附加条件,转载须注明出处:http://blog.csd ...

  7. 【转】 Pro Android学习笔记(六九):HTTP服务(3):HTTP POST MultiPart

    目录(?)[-] 建立测试环境 开发环境导入第三方JAR HTTP Post Multipart小例子 HTTP POST不仅可以通过键值对传递参数,还可以携带更为复杂的参数,例如文件.HTTP Po ...

  8. 【转】 Pro Android学习笔记(三三):Menu(4):Alternative菜单

    目录(?)[-] 什么是Alternative menu替代菜单 小例子说明 Alternative menu代码 关于Category和规范代码写法 关于flags 多个匹配的itemId等参数 什 ...

  9. 【转】 Pro Android学习笔记(二九):用户界面和控制(17):include和merge

    目录(?)[-] xml控件代码重用include xml控件代码重用merge 横屏和竖屏landsacpe portrait xml控件代码重用:include 如果我们定义一个控件,需要在不同的 ...

随机推荐

  1. TOJ 1721 Partial Sums

    Description Given a series of n numbers a1, a2, ..., an, the partial sum of the numbers is defined a ...

  2. JavaScript函数和数组总结

    JavaScript函数 1.      函数的定义 函数名称只能包含字母.数字.下划线或$,且不能以数字开头.定义时可用函数定义表达式或者函数声明语句. var f = function fact( ...

  3. c#-FrameWork01

    Framwork ArrayList l  集合类似于数组,同样是用来存放连续数据的,但集合的功能比数组更强大 l  集合和数组的最大区别:数组一旦定义以后就无法改变其大小,而集合可以动态的改变其大小 ...

  4. CheckBoxList

    CheckBoxList 控件基本用法 定义和用法 CheckBoxList 控件用来建立一个多选的复选框组. CheckBoxList 控件中的每个可选项由一个 ListItem 元素来定义! 提示 ...

  5. c# 字体库跨域解决

    网上大部分的资料说的都是在apache和ng服务器的情况下解决方案,但基本的思路都是添加响应头 场景: 页面引用css文件: <link href="http://www.tuohua ...

  6. javascript:中文等字符转成unicode

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  7. jQuery基础——选择器、效果

    一.使用JS的痛处 在学习和使用js的过程中发现了js的一些痛处: 1.书写繁琐,代码量大. 2.代码复杂. 3.动画效果很难实现.使用定时器,要小心各种定时器的清除.各种操作和处理事件不好实现. 4 ...

  8. 牛客提高R5 A.同余方程

    题意 题目链接 Sol 设\(solve(x, y)\)表示\(i \in [0, x], j \in [0, y]\)满足题目要求的方案数 首先容斥一下,\(ans = solve(r_1, r_2 ...

  9. Disruptor之粗糙认识

    一 概述 1.Disruptor Disruptor是一个高性能的异步处理框架,一个“生产者-消费者”模型. 2.RingBuffer RingBuffer是一种环形数据结构,包含一个指向下一个槽点的 ...

  10. vue使用qrcode生成二维码,可以自定义大小

    1,qrcanvas-vue插件,https://gera2ld.github.io/qrcanvas-vue/#logo.只支持像素大小的二维码 2,qrcode支持移动端自定义大小二维码 &quo ...