Android图片处理(Matrix,ColorMatrix)

转载自:http://www.cnblogs.com/leon19870907/articles/1978065.html

在编程中有时候需要对图片做特殊的处理,比如将图片做出黑白的,或者老照片的效果,有时候还要对图片进行变换,以拉伸,扭曲等等。

这些效果在android中有很好的支持,通过颜色矩阵(ColorMatrix)和坐标变换矩阵(Matrix)可以完美的做出上面的所说的效果。

下面将分别介绍这两个矩阵的用法和相关的函数。

颜色矩阵
android中可以通过颜色矩阵(ColorMatrix类)方面的操作颜色,颜色矩阵是一个5x4 的矩阵(如图1.1)

可以用来方面的修改图片中RGBA各分量的值,颜色矩阵以一维数组的方式存储如下:
 [ a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t ]
他通过RGBA四个通道来直接操作对应颜色,如果会使用Photoshop就会知道有时处理图片通过控制RGBA各颜色通道来做出特殊的效果。

这个矩阵对颜色的作用计算方式如1.3示:


矩阵的运算规则是矩阵A的一行乘以矩阵C的一列作为矩阵R的一行,

C矩阵是图片中包含的ARGB信息,R矩阵是用颜色矩阵应用于C之后的新的颜色分量,运算结果如下:
 
R' = a*R + b*G + c*B + d*A + e;
G' = f*R + g*G + h*B + i*A + j;
B' = k*R + l*G + m*B + n*A + o;
A' = p*R + q*G + r*B + s*A + t;
 
颜色矩阵并不是看上去那么深奥,其实需要使用的参数很少,而且很有规律第一行决定红色第二行决定绿色

,绿色分量增加100,

,图片当然就偏黄了。

改变各颜色分量不仅可以通过修改第5列的颜色偏移量也可如上面矩阵所示将对应的颜色值乘以一个倍数,直接放大。

变为原来的2倍。相信读者至此已经明白了如何通过颜色矩阵来改变各颜色分量。

下面编写一段代码来,通过调整颜色矩阵来获得不同的颜色效果,JavaCode如下:
复制到剪贴板  Java代码

1 CMatrix类: 
2  public class CMatrix extends Activity { 

4 private Button change; 
5 private EditText [] et=new EditText[20]; 
6 private float []carray=new float[20]; 
7 private MyImage sv; 
8 @Override 
9 public void onCreate(Bundle savedInstanceState) { 
10 super.onCreate(savedInstanceState); 
11 setContentView(R.layout.main); 
12 
13 change=(Button)findViewById(R.id.set); 
14 sv=(MyImage)findViewById(R.id.MyImage); 
15 
16 for(int i=0;i<20;i++){ 
17 
18 et[i]=(EditText)findViewById(R.id.indexa+i); 
19 carray[i]=Float.valueOf(et[i].getText().toString()); 
20 } 
21 
22 change.setOnClickListener(l); 
23 } 
24 
25 private Button.OnClickListener l=new Button.OnClickListener(){ 
26 
27 @Override 
28 public void onClick(View arg0) { 
29 // TODO Auto-generated method stub 
30   getValues(); 
31 sv.setValues(carray); 
32 sv.invalidate(); 
33 } 
34 
35 }; 
36 public void getValues(){ 
37 for(int i=0;i<20;i++){ 
38 
39 carray[i]=Float.valueOf(et[i].getText().toString()); 
40 } 
41 
42 } 
43 
44 
45 } 
46 MyImage类继承自View类: 
47 public class MyImage extends View { 
48 private Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); 
49 private Bitmap mBitmap; 
50 private float [] array=new float[20]; 
51 
52 private float mAngle; 
53 
54 public MyImage(Context context,AttributeSet attrs) { 
55 super(context,attrs); 
56 
57 mBitmap = BitmapFactory.decodeResource(context.getResources(), 
58 R.drawable.test); 
59 invalidate(); 
60 } 
61 
62 
63 public void setValues(float [] a){ 
64 for(int i=0;i<20;i++){ 
65 array[i]=a[i]; 
66 } 
67 
68 } 
69 
70 @Override protected void onDraw(Canvas canvas) { 
71 Paint paint = mPaint; 
72 
73 
74 
75 paint.setColorFilter(null); 
76 canvas.drawBitmap(mBitmap, 0, 0, paint); 
77 
78 ColorMatrix cm = new ColorMatrix(); 
79 //设置颜色矩阵 
80 cm.set(array); 
81 //颜色滤镜,将颜色矩阵应用于图片 
82 paint.setColorFilter(new ColorMatrixColorFilter(cm)); 
83 //绘图 
84 canvas.drawBitmap(mBitmap, 0, 0, paint); 
85 Log.i("CMatrix", "--------->onDraw"); 
86 
87 
88 } 
89 
90 }

个数据给颜色矩阵赋值,paint.setColorFilter(..)设置颜色滤镜,然后绘图,效果就出来了(这个过程和PS差不多)如下:





看到这里,相信大家对颜色矩阵的作用已经有了一个直观的感受,现在也可以尝试做一个照片特效的软件。

但是各种效果并不能让用户手动调节颜色矩阵,这里需要计算公式,由于本人并不是做图形软件的也不能提供,可以参考这个链接:
http://www.adobe.com/devnet/flash/articles/matrix_transformations/ColorMatrixDemo.swf

坐标变换矩阵
坐标变换矩阵是一个3*3的矩阵如图2.1,用来对图形进行坐标变化,将原来的坐标点转移到新的坐标点,

因为一个图片是有点阵和每一点上的颜色信息组成的,所以对坐标的变换,就是对每一点进行搬移形成新的图片。

具体的说图形的放大缩小,移动,旋转,透视,扭曲这些效果都可以用此矩阵来完成。


这个矩阵的作用是对坐标x,y进行变换计算结果如下:
x'=a*x+b*y+c
y'=d*x+e*y+f
通常情况下g=h=0,这样使1=0*x+0*y+1恒成立。和颜色矩阵一样,坐标变换矩阵真正使用的参数很少也很有规律。


上图就是一个坐标变换矩阵的简单例子,计算后发现x'=x+50,y'=y+50.

,50)点处,这种效果就是平移效果,将图片转移到了(50,50)处。

计算上面得矩阵x'=2*x,y'=2*y.经过颜色矩阵和上面转移效果学习,相信读者可以明白这个矩阵的作用了,这个矩阵对图片进行了放大,具体的说是放大了二倍。
下面将介绍几种常用的变换矩阵:
1.      旋转


绕原点逆时针旋转θ度角的变换公式是 x' = xcosθ − ysinθ 与 y。' = xsinθ +    ycosθ
2.      缩放

变换后长宽分别放大x'=scale*x;y'=scale*y.
3.         切变

4.         反射

( , )单位向量
5.         正投影

( , )单位向量
 
上面的各种效果也可以叠加在一起,既矩阵的组合变换,可以用矩阵乘法实现之,如:R=B(A*C)=(B*A)C,注意一点就是B*A和A*B一般是不等的。

下面将编一个小程序,通过控制坐标变换矩阵来达到控制图形的目的,JavaCode如下:

复制到剪贴板  Java代码

}

上面的代码中类CooMatrix用于接收用户输入的坐标变换矩阵参数,类MyImage接收参数,通过setValues()设置矩阵参数,然后Canvas调用drawBitmap绘图。效果如下:





上面给出了用坐标变换矩阵做出的各种效果,用坐标变换矩阵可以方面的调节图形的各种效果,

但是我们看看Matrix类就可以发现,实际上,matrix类本身已经提供了许多类似的方法,我们只要调用,就可以了。
 
setScale(float sx, float sy, float px, float py) 放大 
setSkew(float kx, float ky, float px, float py) 斜切 
setTranslate(float dx, float dy)                       平移 
setRotate(float degrees, float px, float py)    旋转 
 
上面的函数提供了基本的变换平移,放大,旋转,斜切。为了做出更复杂的变换,同时不必亲手去改动坐标变换矩阵,

Matrix类提供了许多Map方法,将原图形映射到目标点构成新的图形,

下面简述setPolyToPoly(float[] src, int srcIndex, float[] dst, int dstIndex, int pointCount) 的用法,希望起到举一反三的作用。

参数src和dst是分别存储了原图像的点和和指定的目标点的一维数组,数组中存储的坐标格式如下:
 [x0, y0, x1, y1, x2,y2,...]
 
这个个函数将src中的坐标映射到dst中的坐标,实现图像的变换。

的是原图,写有2,3,4的是变换后的图形。现在分析2是怎么变换来的,变换的原坐标点和目的坐标点如下:
src=new float[] { 32, 32, 64, 32 }
dst=new float[] { 32, 32, 64, 48 }

从上图标示出的坐标看出原图的(32,32)映射到原图的(32,32),(64,32)映射到原图(64,48)这样的效果是图像放大了而且发生了旋转。这样的过程相当于(32,32)点不动,然后拉住图形(64,32)点并拉到(64,48)点处,这样图形必然会被拉伸放大并且发生旋转。最后用一个平移将图形移动到右边现在的位置。希望能够好好理解这一过程,下面的3,4图是同样的道理。

Android图片处理(Matrix,ColorMatrix) - 转载的更多相关文章

  1. android图片处理方法

    Java代码 //压缩图片大小 public static Bitmap compressImage(Bitmap image) { ByteArrayOutputStream baos = new ...

  2. (转)android中颜色矩阵colormatrix

    原文地址:http://www.cnblogs.com/menlsh/archive/2013/02/03/2890888.html 在Android中,对图像进行颜色方面的处理,如黑白老照片.泛黄旧 ...

  3. android图片处理方法(不断收集中)

    //压缩图片大小 public static Bitmap compressImage(Bitmap image) { ByteArrayOutputStream baos = new ByteArr ...

  4. Android 图片处理方法

    //压缩图片大小 public static Bitmap compressImage(Bitmap image) { ByteArrayOutputStream baos = new ByteArr ...

  5. android图片处理方法(转)

    //压缩图片大小 public static Bitmap compressImage(Bitmap image) { ByteArrayOutputStream baos = new ByteArr ...

  6. android 图片解码显示流程

    版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/jingxia2008/article/details/32327699 问题来源 android 能 ...

  7. Android -- 图片处理, 画画板,缩放,旋转,平移,镜面,倒影,图片合成,颜色处理

    1. 画画板 示例代码 public class MainActivity extends Activity { private ImageView iv; private Bitmap baseBi ...

  8. Android 图片压缩器

    概述 Android 图片压缩器:一款高效的图片压缩器库,支持批量压缩,异步压缩.多线程多任务压缩,压缩比设置等特性. 详细 代码下载:http://www.demodashi.com/demo/12 ...

  9. android图片缩放平移

    <?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android=" ...

随机推荐

  1. MFC使用自定义资源加载PNG

    app.h #define RES_PNG _T("PNG")#define RES_JPEG _T("JPEG")#define RES_JIF _T(&qu ...

  2. Entity Framework应用:导航属性

    一.主键和外键 关系型数据库中的一条记录中有若干个属性,若其中某一个属性组是能唯一标识一条记录,该属性组就可以称为主键.例如: 学生版(学号.姓名.性别.班级) 其中每个学生的学号是唯一的,学号就是一 ...

  3. java 生成指定区间随机数

    int randNumber =rand.nextInt(MAX - MIN + 1) + MIN; // randNumber 将被赋值为一个 MIN 和 MAX 范围内的随机数

  4. eclipse如何设置高亮代码的背景色,比如选中某个单词,高亮所有的

    设置方法如下: 1.单击IDE顶部Window菜单下的Prefences,如图: 2.在打开对话框的左侧树上,找到Java节点下的Editor中的Mark Occurren,如图: 3.点击Mark ...

  5. org.apache.catalina.LifecycleException异常的处理

    今天调试了很久,重装tomcat都没用,后来发现是xml servlet的url-pattern的配置少写一个"/",添加后启动即可. org.apache.catalina.Li ...

  6. 为HTML5开发人员量身打造的7个Web框架

    HTML5规范开发完成时,将成为主流.据统计2013年全球将有10亿手机浏览器支持HTML5,同时HTML Web开发者数量将达到200万.毫无疑问,HTML5将成为未来5-10年内,移动互联网领域的 ...

  7. apt-get 命令加 autoclean clean autoremove 区别

    下面总结一下有关apt-get的常用但容易混淆的指令: apt-get autoclean:   www.2cto.com       如果你的硬盘空间不大的话,可以定期运行这个程序,将已经删除了的软 ...

  8. sublime text 2使用方法

    笔者用过的一些软件用来写Verilog代码,比如notepad+,ultra,editplus等,近日在群里看到大家在讨论一个比较有意思的软件,sublime text,才发现有种相见恨晚的感觉,其实 ...

  9. Self20171218_Eclipse+TestNg HelloWorld

    作为一个经典的入门例子,这里展示如何开始使用TestNG单元测试框架. 使用的工具 : TestNG 6.8.7 Maven 3 Eclipse IDE TestNG下载并安装 从这里 http:// ...

  10. 【转】【Python】Python中的__init__.py与模块导入(from import 找不到模块的问题)

    python中的Module是比较重要的概念.常见的情况是,事先写好一个.py文 件,在另一个文件中需要import时,将事先写好的.py文件拷贝 到当前目录,或者是在sys.path中增加事先写好的 ...