Android 图像处理 matrix ColorMatrix 旋转移动

目录(?)[+]

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

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

一. 显示打开图片

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

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

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

[java] view plain copy print ?
  1. privateButtonselectBn;
  2. privateImageViewimageShow;
  3. privateImageViewimageCreate;
  4. privateTextViewtextview1;
  5. privateTextViewtextview2;
  6. privateBitmapbmp;//原始图片
  7. @Override
  8. protectedvoidonCreate(BundlesavedInstanceState){
  9. super.onCreate(savedInstanceState);
  10. setContentView(R.layout.activity_main);
  11. selectBn=(Button)findViewById(R.id.button1);
  12. imageShow=(ImageView)findViewById(R.id.imageView1);
  13. imageCreate=(ImageView)findViewById(R.id.imageView2);
  14. textview1=(TextView)findViewById(R.id.textView1);
  15. textview2=(TextView)findViewById(R.id.textView2);
  16. //选择图片
  17. selectBn.setOnClickListener(newOnClickListener(){
  18. @Override
  19. publicvoidonClick(Viewv){
  20. Intentintent=newIntent(Intent.ACTION_PICK,
  21. android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
  22. startActivityForResult(intent,0);
  23. }
  24. });
  25. if(savedInstanceState==null){
  26. getFragmentManager().beginTransaction()
  27. .add(R.id.container,newPlaceholderFragment())
  28. .commit();
  29. }
  30. }
  31. //显示两张图片
  32. protectedvoidonActivityResult(intrequestCode,intresultCode,Intentdata){
  33. super.onActivityResult(requestCode,resultCode,data);
  34. if(resultCode==RESULT_OK){
  35. ShowPhotoByImageView(data);//显示照片
  36. CreatePhotoByImageView();//创建图片
  37. }
  38. }

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

[java] view plain copy print ?
  1. //自定义函数显示打开的照片在ImageView1中
  2. publicvoidShowPhotoByImageView(Intentdata){
  3. UriimageFileUri=data.getData();
  4. DisplayMetricsdm=newDisplayMetrics();
  5. getWindowManager().getDefaultDisplay().getMetrics(dm);
  6. intwidth=dm.widthPixels;//手机屏幕水平分辨率
  7. intheight=dm.heightPixels;//手机屏幕垂直分辨率
  8. Log.v("height",""+height);
  9. Log.v("width",""+width);
  10. try{
  11. //Loaduptheimage'sdimensionsnottheimageitself
  12. BitmapFactory.OptionsbmpFactoryOptions=newBitmapFactory.Options();
  13. bmpFactoryOptions.inJustDecodeBounds=true;
  14. bmp=BitmapFactory.decodeStream(getContentResolver().openInputStream(imageFileUri),null,bmpFactoryOptions);
  15. intheightRatio=(int)Math.ceil(bmpFactoryOptions.outHeight/(float)height);
  16. intwidthRatio=(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(FileNotFoundExceptione){
  33. e.printStackTrace();
  34. }
  35. }
  36. //创建第二张图片并显示
  37. publicvoidCreatePhotoByImageView(){
  38. try{
  39. BitmapcreateBmp=Bitmap.createBitmap(bmp.getWidth(),bmp.getHeight(),bmp.getConfig());
  40. Canvascanvas=newCanvas(createBmp);//画布传入位图用于绘制
  41. Paintpaint=newPaint();//画刷改变颜色对比度等属性
  42. canvas.drawBitmap(bmp,0,0,paint);//错误:没有图片因为参数bmp写成createBmp
  43. imageCreate.setImageBitmap(createBmp);
  44. textview2.setVisibility(View.VISIBLE);
  45. }catch(Exceptione){
  46. e.printStackTrace();
  47. }
  48. }

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

二. Matrix操作

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

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

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

[java] view plain copy print ?
  1. //缩小图片
  2. privatevoidSmallPicture(){
  3. Matrixmatrix=newMatrix();
  4. //缩放区间0.5-1.0
  5. if(smallbig>0.5f)
  6. smallbig=smallbig-0.1f;
  7. else
  8. smallbig=0.5f;
  9. //xy坐标同时缩放
  10. matrix.setScale(smallbig,smallbig,bmp.getWidth()/2,bmp.getHeight()/2);
  11. BitmapcreateBmp=Bitmap.createBitmap(bmp.getWidth(),bmp.getHeight(),bmp.getConfig());
  12. Canvascanvas=newCanvas(createBmp);//画布传入位图用于绘制
  13. Paintpaint=newPaint();//画刷改变颜色对比度等属性
  14. canvas.drawBitmap(bmp,matrix,paint);
  15. imageCreate.setBackgroundColor(Color.RED);
  16. imageCreate.setImageBitmap(createBmp);
  17. textview2.setVisibility(View.VISIBLE);
  18. }
  19. //放大图片
  20. privatevoidBigPicture(){
  21. Matrixmatrix=newMatrix();
  22. //缩放区间0.5-1.0
  23. if(smallbig<1.5f)
  24. smallbig=smallbig+0.1f;
  25. else
  26. smallbig=1.5f;
  27. //xy坐标同时缩放
  28. matrix.setScale(smallbig,smallbig,bmp.getWidth()/2,bmp.getHeight()/2);
  29. BitmapcreateBmp=Bitmap.createBitmap(bmp.getWidth(),bmp.getHeight(),bmp.getConfig());
  30. Canvascanvas=newCanvas(createBmp);
  31. Paintpaint=newPaint();
  32. canvas.drawBitmap(bmp,matrix,paint);
  33. imageCreate.setBackgroundColor(Color.RED);
  34. imageCreate.setImageBitmap(createBmp);
  35. textview2.setVisibility(View.VISIBLE);
  36. }
  37. //旋转图片
  38. privatevoidTurnPicture(){
  39. Matrixmatrix=newMatrix();
  40. turnRotate=turnRotate+15;
  41. //选择角度饶(0,0)点选择正数顺时针负数逆时针中心旋转
  42. matrix.setRotate(turnRotate,bmp.getWidth()/2,bmp.getHeight()/2);
  43. BitmapcreateBmp=Bitmap.createBitmap(bmp.getWidth(),bmp.getHeight(),bmp.getConfig());
  44. Canvascanvas=newCanvas(createBmp);
  45. Paintpaint=newPaint();
  46. canvas.drawBitmap(bmp,matrix,paint);
  47. imageCreate.setBackgroundColor(Color.RED);
  48. imageCreate.setImageBitmap(createBmp);
  49. textview2.setVisibility(View.VISIBLE);
  50. }
  51. //改变图像饱和度
  52. privatevoidSaturationPicture(){
  53. //设置饱和度0表示灰度图像大于1饱和度增加0-1饱和度减小
  54. ColorMatrixcm=newColorMatrix();
  55. cm.setSaturation(saturation);
  56. Paintpaint=newPaint();
  57. paint.setColorFilter(newColorMatrixColorFilter(cm));
  58. //显示图片
  59. Matrixmatrix=newMatrix();
  60. BitmapcreateBmp=Bitmap.createBitmap(bmp.getWidth(),bmp.getHeight(),bmp.getConfig());
  61. Canvascanvas=newCanvas(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. privatevoidContrastPicture(){
  72. ColorMatrixcm=newColorMatrix();
  73. floatbrightness=-25;//亮度
  74. floatcontrast=2;//对比度
  75. cm.set(newfloat[]{
  76. contrast,0,0,0,brightness,
  77. 0,contrast,0,0,brightness,
  78. 0,0,contrast,0,brightness,
  79. 0,0,0,contrast,0
  80. });
  81. Paintpaint=newPaint();
  82. paint.setColorFilter(newColorMatrixColorFilter(cm));
  83. //显示图片
  84. Matrixmatrix=newMatrix();
  85. BitmapcreateBmp=Bitmap.createBitmap(bmp.getWidth(),bmp.getHeight(),bmp.getConfig());
  86. Canvascanvas=newCanvas(createBmp);
  87. canvas.drawBitmap(bmp,matrix,paint);
  88. imageCreate.setImageBitmap(createBmp);
  89. textview2.setVisibility(View.VISIBLE);
  90. }

同时自定义变量如下:

[java] view plain copy print ?
  1. //图片变换参数
  2. privatefloatsmallbig=1.0f;//缩放比例
  3. privateintturnRotate=0;//旋转度数
  4. privatefloatsaturation=0f;//饱和度

它的运行结果如下图所示:



需要指出的是:该项目仅仅讲述处理的过程,并没有考虑很多因素,如:有的图像显示可能超出屏幕,没有载入图片点击处理按钮报错,横竖屏切换导致不显示图片,最下面按钮可能被遮挡,图像放大画布没有变,因为为认为显示一张改变后的图片效果更好,而该工程仅仅是对比.图像缩放移动触屏变换更好,下一篇讲述.
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. Matrixmatrix=newMatrix();
  2. matrix.setValues(newfloat[]{
  3. 1,0,0,
  4. 0,1,0,
  5. 0,0,1
  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)

更多相关文章

  1. Android:TextView的常用功能
  2. android之eclipse下查看android系统源代码
  3. Android使用Opencv图片处理 Mat与Bitmap互转
  4. Android(安卓)TextView文字横向自动滚动(跑马灯)
  5. android中使用线程池和临时缓存优化网络图片加载
  6. 【Android(安卓)4.0】Android(安卓)Icon Set的使用
  7. 发现自己喜欢了移动端开发--Android
  8. Android获取屏幕分辨率及DisplayMetrics简介
  9. Android之怎么使用SQLite数据库(增、删、改、查、分页等)以及Lis

随机推荐

  1. bootstrap-multiselect 多选实例代码
  2. 详解可选参数和命名参数实例
  3. 分享一个IoC入门教程实例
  4. [转]Composite Keys With WebApi OData
  5. 总结EF通用数据层封装类实例详解
  6. [转]Support Composite Key in ASP.NET W
  7. 学习ASP.NET Core 2遇到的问题分享
  8. 使用ConcurrentDictionary多线程同步字典
  9. 浅谈WPF之Binding表达式
  10. 一个很强大的控件--PropertyGrid