[Android] 使用Matrix矩阵类对图像进行缩放、旋转、对比度、亮度处理


        
Android 图像处理 matrix ColorMatrix 旋转移动

目录(?)[+]

  1. 一 显示打开图片
  2. 二 Matrix操作
  3. 三 Matrix处理的原理

    前一篇文章讲述了Android拍照、截图、保存并显示在ImageView控件中,该篇文章继续讲述Android图像处理技术,主要操作包括:通过打开相册里的图片,使用Matrix对图像进行缩放、旋转、移动、对比度、亮度、饱和度操作,希望对大家有所帮助.

一. 显示打开图片

    首先,设置activity_main.xml布局如下所示:

[html] view plain copy print ?
  1. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  2.     xmlns:tools="http://schemas.android.com/tools"  
  3.     android:id="@+id/container"  
  4.     android:layout_width="match_parent"  
  5.     android:layout_height="wrap_content"  
  6.     tools:context="com.example.cangeimagetest.MainActivity"  
  7.     tools:ignore="MergeRootFrame" >  
  8.       
  9.     <LinearLayout   
  10.         android:layout_width="match_parent"  
  11.         android:layout_height="wrap_content"  
  12.         android:orientation="vertical" >      
  13.         <Button  
  14.             android:id="@+id/button1"  
  15.             android:layout_width="match_parent"  
  16.             android:layout_height="wrap_content"  
  17.             android:text="选择图片" />  
  18.         <TextView  
  19.             android:id="@+id/textView1"  
  20.             android:layout_width="match_parent"  
  21.             android:layout_height="wrap_content"  
  22.             android:visibility="invisible"  
  23.             android:text="原图显示" />  
  24.         <ImageView  
  25.             android:id="@+id/imageView1"  
  26.             android:layout_width="wrap_content"  
  27.             android:layout_gravity="center_horizontal"  
  28.             android:layout_height="wrap_content" />  
  29.         <TextView  
  30.             android:id="@+id/textView2"  
  31.             android:layout_width="match_parent"  
  32.             android:layout_height="wrap_content"  
  33.             android:visibility="invisible"  
  34.             android:text="变化后的图片" />  
  35.         <ImageView  
  36.             android:id="@+id/imageView2"  
  37.             android:layout_gravity="center_horizontal"  
  38.             android:layout_marginBottom="20dp"   
  39.             android:layout_width="wrap_content"  
  40.             android:layout_height="wrap_content" />  
  41.     </LinearLayout>  
  42.       
  43.     <LinearLayout   
  44.         android:layout_width="match_parent"  
  45.         android:layout_height="wrap_content"  
  46.         android:orientation="horizontal"  
  47.         android:layout_alignParentBottom="true" >  
  48.         <Button  
  49.             android:id="@+id/button2"  
  50.             android:layout_width="wrap_content"  
  51.             android:layout_height="match_parent"  
  52.             android:layout_weight="1"  
  53.             android:text="缩小" />  
  54.         <Button  
  55.             android:id="@+id/button3"  
  56.             android:layout_width="wrap_content"  
  57.             android:layout_height="match_parent"  
  58.             android:layout_weight="1"  
  59.             android:text="放大" />  
  60.         <Button  
  61.             android:id="@+id/button4"  
  62.             android:layout_width="wrap_content"  
  63.             android:layout_height="match_parent"  
  64.             android:layout_weight="1"  
  65.             android:text="旋转" />  
  66.         <Button  
  67.             android:id="@+id/button5"  
  68.             android:layout_width="wrap_content"  
  69.             android:layout_height="match_parent"  
  70.             android:layout_weight="1"  
  71.             android:text="饱和" />  
  72.         <Button  
  73.             android:id="@+id/button6"  
  74.             android:layout_width="wrap_content"  
  75.             android:layout_height="match_parent"  
  76.             android:layout_weight="1"  
  77.             android:text="对比" />  
  78.     </LinearLayout>  
  79. </RelativeLayout>  

    然后,在Mainctivity.java中public class MainActivity extends Activity函数添加代码如下:

[java] view plain copy print ?
  1. private Button selectBn;  
  2. private ImageView imageShow;  
  3. private ImageView imageCreate;  
  4. private TextView textview1;  
  5. private TextView textview2;  
  6. private Bitmap bmp; //原始图片  
  7.   
  8. @Override  
  9. protected void onCreate(Bundle savedInstanceState) {  
  10.     super.onCreate(savedInstanceState);  
  11.     setContentView(R.layout.activity_main);  
  12.     selectBn = (Button) findViewById(R.id.button1);  
  13.     imageShow = (ImageView) findViewById(R.id.imageView1);  
  14.     imageCreate = (ImageView) findViewById(R.id.imageView2);  
  15.     textview1 = (TextView) findViewById(R.id.textView1);  
  16.     textview2 = (TextView) findViewById(R.id.textView2);  
  17.       
  18.     //选择图片  
  19.     selectBn.setOnClickListener(new OnClickListener() {  
  20.         @Override  
  21.         public void onClick(View v) {  
  22.             Intent intent = new Intent(Intent.ACTION_PICK,   
  23.                     android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);  
  24.             startActivityForResult(intent, 0 );  
  25.         }  
  26.     });  
  27.     if (savedInstanceState == null) {  
  28.         getFragmentManager().beginTransaction()  
  29.                 .add(R.id.container, new PlaceholderFragment())  
  30.                 .commit();  
  31.     }  
  32. }  
  33. //显示两张图片  
  34. protected void onActivityResult(int requestCode, int resultCode, Intent data) {    
  35.     super.onActivityResult(requestCode, resultCode, data);  
  36.     if(resultCode==RESULT_OK) {  
  37.         ShowPhotoByImageView(data);     //显示照片  
  38.         CreatePhotoByImageView();          //创建图片  
  39.     }  
  40. }  

    再调用自定义函数实现显示图片:

[java] view plain copy print ?
  1. //自定义函数 显示打开的照片在ImageView1中  
  2. public void ShowPhotoByImageView(Intent data) {  
  3.     Uri imageFileUri = data.getData();  
  4.     DisplayMetrics dm = new DisplayMetrics();  
  5.     getWindowManager().getDefaultDisplay().getMetrics(dm);  
  6.     int width = dm.widthPixels;    //手机屏幕水平分辨率  
  7.     int height = dm.heightPixels;  //手机屏幕垂直分辨率  
  8.     Log.v("height"""+height );  
  9.     Log.v("width"""+width);  
  10.     try {  
  11.         // Load up the image's dimensions not the image itself  
  12.         BitmapFactory.Options bmpFactoryOptions = new BitmapFactory.Options();  
  13.         bmpFactoryOptions.inJustDecodeBounds = true;  
  14.         bmp = BitmapFactory.decodeStream(getContentResolver().openInputStream(imageFileUri), null, bmpFactoryOptions);  
  15.         int heightRatio = (int)Math.ceil(bmpFactoryOptions.outHeight/(float)height);  
  16.         int widthRatio = (int)Math.ceil(bmpFactoryOptions.outWidth/(float)width);  
  17.         Log.v("bmpheight"""+bmpFactoryOptions.outHeight);  
  18.         Log.v("bmpheight"""+bmpFactoryOptions.outWidth);  
  19.         if(heightRatio>1&&widthRatio>1) {  
  20.             if(heightRatio>widthRatio) {  
  21.                 bmpFactoryOptions.inSampleSize = heightRatio*2;  
  22.             }  
  23.             else {  
  24.                 bmpFactoryOptions.inSampleSize = widthRatio*2;  
  25.             }  
  26.         }  
  27.          //图像真正解码     
  28.         bmpFactoryOptions.inJustDecodeBounds = false;                 
  29.         bmp = BitmapFactory.decodeStream(getContentResolver().openInputStream(imageFileUri), null, bmpFactoryOptions);    
  30.         imageShow.setImageBitmap(bmp); //将剪裁后照片显示出来    
  31.         textview1.setVisibility(View.VISIBLE);  
  32.     } catch(FileNotFoundException e) {  
  33.         e.printStackTrace();  
  34.     }  
  35. }  
  36. //创建第二张图片并显示  
  37. public void CreatePhotoByImageView() {  
  38.     try {  
  39.         Bitmap createBmp = Bitmap.createBitmap(bmp.getWidth(), bmp.getHeight(), bmp.getConfig());  
  40.         Canvas canvas = new Canvas(createBmp); //画布 传入位图用于绘制  
  41.         Paint paint = new Paint(); //画刷 改变颜色 对比度等属性  
  42.         canvas.drawBitmap(bmp, 00, paint);    //错误:没有图片 因为参数bmp写成createBmp  
  43.         imageCreate.setImageBitmap(createBmp);  
  44.         textview2.setVisibility(View.VISIBLE);  
  45.     } catch(Exception e) {  
  46.         e.printStackTrace();  
  47.     }  
  48. }  

    显示的效果如下图所示,该图叫莱娜图(Lenna),是图像处理中经常使用的样例图.

[Android] 使用Matrix矩阵类对图像进行缩放、旋转、对比度、亮度处理_第1张图片

二. Matrix操作

   然后通过Matrix对图像进行处理操作,在onCreate函数中添加点击事件:

[java] view plain copy print ?
  1. //缩小图片  
  2. Button button2=(Button)findViewById(R.id.button2);  
  3. button2.setOnClickListener(new OnClickListener() {  
  4.     @Override  
  5.     public void onClick(View v) {  
  6.         SmallPicture();  
  7.     }  
  8. });  
  9. //放大图片  
  10.     Button button3=(Button)findViewById(R.id.button3);  
  11.     button3.setOnClickListener(new OnClickListener() {  
  12.         @Override  
  13.         public void onClick(View v) {  
  14.             BigPicture();  
  15.         }  
  16.     });  
  17.    //旋转图片  
  18. Button button4=(Button)findViewById(R.id.button4);  
  19. button4.setOnClickListener(new OnClickListener() {  
  20.     @Override  
  21.     public void onClick(View v) {  
  22.         TurnPicture();  
  23.     }  
  24. });  
  25. //图片饱和度改变  
  26. Button button5=(Button)findViewById(R.id.button5);  
  27. button5.setOnClickListener(new OnClickListener() {  
  28.     @Override  
  29.     public void onClick(View v) {  
  30.         SaturationPicture();  
  31.     }  
  32. });  
  33. //图片对比度改变  
  34. Button button6=(Button)findViewById(R.id.button6);  
  35. button6.setOnClickListener(new OnClickListener() {  
  36.     @Override  
  37.     public void onClick(View v) {  
  38.         ContrastPicture();  
  39.     }  
  40. });  

    最后分别自定义函数各操作实现,代码如下:

[java] view plain copy print ?
  1. //缩小图片  
  2. private void SmallPicture() {  
  3.     Matrix matrix = new Matrix();  
  4.     //缩放区间 0.5-1.0  
  5.     if(smallbig>0.5f)  
  6.         smallbig=smallbig-0.1f;  
  7.     else  
  8.         smallbig=0.5f;  
  9.     //x y坐标同时缩放  
  10.     matrix.setScale(smallbig,smallbig,bmp.getWidth()/2,bmp.getHeight()/2);   
  11.     Bitmap createBmp = Bitmap.createBitmap(bmp.getWidth(), bmp.getHeight(), bmp.getConfig());  
  12.     Canvas canvas = new Canvas(createBmp); //画布 传入位图用于绘制  
  13.     Paint paint = new Paint(); //画刷 改变颜色 对比度等属性  
  14.         canvas.drawBitmap(bmp, matrix, paint);  
  15.         imageCreate.setBackgroundColor(Color.RED);  
  16.         imageCreate.setImageBitmap(createBmp);  
  17.         textview2.setVisibility(View.VISIBLE);  
  18.     }  
  19.   //放大图片  
  20. private void BigPicture() {  
  21.     Matrix matrix = new Matrix();  
  22.     //缩放区间 0.5-1.0  
  23.     if(smallbig<1.5f)  
  24.         smallbig=smallbig+0.1f;  
  25.     else  
  26.         smallbig=1.5f;  
  27.     //x y坐标同时缩放  
  28.     matrix.setScale(smallbig,smallbig,bmp.getWidth()/2,bmp.getHeight()/2);   
  29.     Bitmap createBmp = Bitmap.createBitmap(bmp.getWidth(), bmp.getHeight(), bmp.getConfig());  
  30.     Canvas canvas = new Canvas(createBmp);   
  31.     Paint paint = new Paint();   
  32.     canvas.drawBitmap(bmp, matrix, paint);  
  33.     imageCreate.setBackgroundColor(Color.RED);  
  34.     imageCreate.setImageBitmap(createBmp);  
  35.     textview2.setVisibility(View.VISIBLE);  
  36. }  
  37. //旋转图片  
  38. private void TurnPicture() {  
  39.     Matrix matrix = new Matrix();  
  40.     turnRotate=turnRotate+15;  
  41.     //选择角度 饶(0,0)点选择 正数顺时针 负数逆时针 中心旋转  
  42.     matrix.setRotate(turnRotate,bmp.getWidth()/2,bmp.getHeight()/2);   
  43.     Bitmap createBmp = Bitmap.createBitmap(bmp.getWidth(), bmp.getHeight(), bmp.getConfig());  
  44.     Canvas canvas = new Canvas(createBmp);   
  45.     Paint paint = new Paint();   
  46.     canvas.drawBitmap(bmp, matrix, paint);  
  47.     imageCreate.setBackgroundColor(Color.RED);  
  48.     imageCreate.setImageBitmap(createBmp);  
  49.     textview2.setVisibility(View.VISIBLE);  
  50. }  
  51. //改变图像饱和度  
  52. private void SaturationPicture() {  
  53.     //设置饱和度 0表示灰度图像 大于1饱和度增加 0-1饱和度减小  
  54.     ColorMatrix cm = new ColorMatrix();  
  55.     cm.setSaturation(saturation);  
  56.     Paint paint = new Paint();   
  57.     paint.setColorFilter(new ColorMatrixColorFilter(cm));  
  58.     //显示图片  
  59.     Matrix matrix = new Matrix();  
  60.     Bitmap createBmp = Bitmap.createBitmap(bmp.getWidth(), bmp.getHeight(), bmp.getConfig());  
  61.     Canvas canvas = new Canvas(createBmp);   
  62.     canvas.drawBitmap(bmp, matrix, paint);  
  63.     imageCreate.setImageBitmap(createBmp);  
  64.     textview2.setVisibility(View.VISIBLE);  
  65.     saturation=saturation+0.1f;  
  66.     if(saturation>=1.5f) {  
  67.         saturation=0f;  
  68.     }  
  69. }  
  70. //设置图片对比度  
  71. private void ContrastPicture() {  
  72.     ColorMatrix cm = new ColorMatrix();  
  73.     float brightness = -25;  //亮度  
  74.     float contrast = 2;        //对比度  
  75.     cm.set(new float[] {  
  76.         contrast, 000, brightness,  
  77.         0, contrast, 00, brightness,  
  78.         00, contrast, 0, brightness,  
  79.         000, contrast, 0  
  80.     });  
  81.     Paint paint = new Paint();   
  82.     paint.setColorFilter(new ColorMatrixColorFilter(cm));  
  83.     //显示图片  
  84.     Matrix matrix = new Matrix();  
  85.     Bitmap createBmp = Bitmap.createBitmap(bmp.getWidth(), bmp.getHeight(), bmp.getConfig());  
  86.     Canvas canvas = new Canvas(createBmp);   
  87.     canvas.drawBitmap(bmp, matrix, paint);  
  88.     imageCreate.setImageBitmap(createBmp);  
  89.     textview2.setVisibility(View.VISIBLE);  
  90. }  

    同时自定义变量如下:

[java] view plain copy print ?
  1. //图片变换参数  
  2. private float smallbig=1.0f;   //缩放比例  
  3. private int turnRotate=0;       //旋转度数  
  4. private float saturation=0f;    //饱和度  

    它的运行结果如下图所示:
[Android] 使用Matrix矩阵类对图像进行缩放、旋转、对比度、亮度处理_第2张图片   [Android] 使用Matrix矩阵类对图像进行缩放、旋转、对比度、亮度处理_第3张图片
[Android] 使用Matrix矩阵类对图像进行缩放、旋转、对比度、亮度处理_第4张图片   [Android] 使用Matrix矩阵类对图像进行缩放、旋转、对比度、亮度处理_第5张图片
[Android] 使用Matrix矩阵类对图像进行缩放、旋转、对比度、亮度处理_第6张图片   [Android] 使用Matrix矩阵类对图像进行缩放、旋转、对比度、亮度处理_第7张图片
    需要指出的是:该项目仅仅讲述处理的过程,并没有考虑很多因素,如:有的图像显示可能超出屏幕,没有载入图片点击处理按钮报错,横竖屏切换导致不显示图片,最下面按钮可能被遮挡,图像放大画布没有变,因为为认为显示一张改变后的图片效果更好,而该工程仅仅是对比.图像缩放移动触屏变换更好,下一篇讲述.
    XML布局推荐:http://www.apkbus.com/forum.php?mod=viewthread&tid=44949
    解决画布跟着图片放大:http://www.eoeandroid.com/thread-3162-1-1.html

三. Matrix处理的原理

    Android中可以通过Matrix和ColorMatrix对图像进行处理.
   
1.Matrix
    图像空间变换,包括旋转、剪裁、缩放或移动.Matrix类中每个数字都将应用于图像上每个点的3个坐标x\y\z之一.
   
如下代码通过setValues设置值.(1,0,0)表示x坐标转换x=1x+0y+0z,同样y=0x+1y+0z,z=0x+0y+1z.该矩阵不做任何变换.如果第一行改为(.5f,0,0),那么图像在x轴上将图像压缩50%.移动见setTranslate()函数.

[java] view plain copy print ?
  1. Matrix matrix = new Matrix();  
  2. matrix.setValues(new float[] {  
  3.         100,  
  4.         010,  
  5.         001  
  6. });  

    2.ColorMatrix
    在Canvas(画布)对象上绘制时既可使用Matrix方法,也可使用ColorMatrix来改变在Canvas对象上绘制的Paint(画刷)对象.对图像的像素处理时,每个像素由RGBA值组成(Red Green Blue Alpha).具体方法推荐博文:http://www.cnblogs.com/leon19870907/articles/1978065.html
    最后希望该文章对大家有所帮助,尤其是Android初学者.该文章是讲述Android使用Matrix处理图片的基础文章,如果有不足或错误地方,请见谅~参考资料《Android多媒体开发高级编程 著:Shawn Van Every
    下载地址:http://download.csdn.net/detail/eastmount/8082043
(By:Eastmount 2014-10-26 夜2点
http://blog.csdn.net/eastmount)
 

你可能感兴趣的:([Android] 使用Matrix矩阵类对图像进行缩放、旋转、对比度、亮度处理)