`
熊滔爱孟涛静
  • 浏览: 124660 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

android colormatrix

 
阅读更多

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

这些效果在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;
 
颜色矩阵并不是看上去那么深奥,其实需要使用的参数很少,而且很有规律第一行决定红色第二行决定绿色

第三行决定蓝色,第四行决定了透明度,第五列是颜色的偏移量。下面是一个实际中使用的颜色矩阵。


如果把这个矩阵作用于各颜色分量的话,R=A*C,计算后会发现,各个颜色分量实际上没有任何的改变(R'=R G'=G B'=B A'=A)。

图1.5所示矩阵计算后会发现红色分量增加100,绿色分量增加100,

这样的效果就是图片偏黄,因为红色和绿色混合后得到黄色,黄色增加了100,图片当然就偏黄了。

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

上图1.6是将绿色分量乘以2变为原来的2倍。相信读者至此已经明白了如何通过颜色矩阵来改变各颜色分量。

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

1 CMatrix类:
2  public class CMatrix extends Activity {
3
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 }


CMatrix类主要负责接收颜色矩阵的设置和重绘,没有要说的。MyImage类中进行绘图工作,首先设置颜色矩阵cm.set(..)从一维数组中读取数据20个数据给颜色矩阵赋值,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.

可见图片的每一点都在x和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代码

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



上面的代码中类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中的坐标,实现图像的变换。

具体的例子可以参考APIDemos里的PolyToPoly,我在这里就不再贴代码了,只讲一下函数是怎么变换图片的。下面是效果:


图中写1的是原图,写有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 ColorMatrix的例子

    在Android开发中,`ColorMatrix`是一个非常重要的工具类,用于处理颜色变换和图像滤镜效果。`ColorMatrix`类提供了对颜色空间进行线性变换的功能,可以用来改变图像的颜色饱和度、亮度、对比度,甚至实现一些特殊的...

    android ColorMatrix

    在Android开发中,`ColorMatrix`是一个非常重要的工具类,用于处理颜色变换。它提供了对图像像素颜色进行矩阵运算的功能,允许开发者实现各种颜色效果,如灰度转换、色彩饱和度调整、色调旋转等。本项目是使用...

    图像颜色处理(ColorMatrix)源码

    `ColorMatrix`类是Android SDK提供的一种工具,用于执行复杂的颜色空间转换和图像滤镜操作。这个源码分析将深入探讨`ColorMatrix`的工作原理以及如何在实际应用中使用它。 首先,`ColorMatrix`类是一个4x5的矩阵,...

    Android图片各种处理效果源码

    Android图片效果: "图片缩放", "图片圆角", "图片倒影", "旋转图片", "图片反转", "图片色调饱和度、色相、亮度处理", "涂鸦,水印", "图片上写文字", "怀旧效果", "模糊效果" ,"柔化效果(高斯模糊)", "浮雕效果...

    实战Android:图片处理之ColorMatrix和Matrix实例

    理解并熟练掌握`ColorMatrix`和`Matrix`的使用,不仅可以提升Android应用的视觉效果,还能帮助开发者在处理图像时有更多创新。在实际项目中,这些技术可以应用于相机滤镜、自定义控件的动画效果,甚至游戏中的图形...

    Android下图片颜色变换处理Demo

    `ColorMatrix`是Android SDK提供的一种强大的工具,它允许开发者对图像的颜色进行各种操作,如调整亮度、对比度、饱和度,甚至进行色彩空间转换。 首先,我们需要理解`ColorMatrix`的基本原理。`ColorMatrix`是一个...

    Android 矩阵ColorMatrix

    Android中的ColorMatrix是一个强大的工具,用于在图像处理中实现色彩变换。它基于数学中的矩阵运算,特别适用于对图像的色彩饱和度、亮度、对比度以及色调等属性进行调整。下面我们将深入探讨ColorMatrix的原理、...

    android完美的图片滤镜效果

    本教程将详细探讨如何在Android中实现完美的图片滤镜效果,主要基于ColorMatrix类,这个类是Android图形处理中的核心组件,可以方便地对图像的颜色进行调整。 首先,我们需要理解什么是ColorMatrix。ColorMatrix是...

    android获取灰度图片

    ### Android 获取灰度图片知识点详解 #### 一、概述 在Android开发中,有时需要将彩色图片转换为灰度图片,以实现特定的功能或视觉效果。例如,在即时通讯应用中,通常会用彩色头像表示用户在线状态,而用灰度头像...

    android动态改变图片颜色(纯色)

    在Android开发中,有时我们需要根据应用的运行状态或者用户的交互来动态改变图片的颜色。这个功能在许多场景下都非常实用,比如主题切换、夜间模式切换或者是按钮的状态变化等。标题所提及的“android动态改变图片...

    android图片置灰

    Android提供了`ColorMatrix`类,通过设置颜色矩阵,可以对图片进行各种色彩转换,包括置灰。首先创建一个`ColorMatrix`对象,然后设置一个灰度转换矩阵,例如:`{0.3f, 0.59f, 0.11f, 0, 0, 0.3f, 0.59f, 0.11f, 0,...

    android Bitmap特效处理

    Android提供了ColorMatrix类,可以用于调整颜色矩阵,从而实现灰度转换。通过设置ColorMatrix的各个通道权重(红色、绿色、蓝色和 alpha),我们可以将彩色图像转换为灰度图像。 接下来是**底片特效**,也称为负片...

    Android图像处理技术(实现Android中的PS)(四)

    在Android平台上,图像处理技术是移动应用开发中的一个重要领域,特别是在构建类似Photoshop(PS)功能的应用时。本文将深入探讨如何在Android中实现复杂的图像处理功能,为用户提供丰富的图片编辑体验。 一、...

    Android-BreatheView呼吸灯闪烁效果的自定义View

    在Android开发中,自定义View是一种常见的需求,用于实现独特的用户界面或动画效果。本案例中的"Android-BreatheView呼吸灯闪烁效果的自定义View"是一个专门设计用来模拟呼吸灯闪烁效果的自定义组件。这种效果常常...

    android图片灰度处理

    2. **使用ColorMatrix**:Android提供了ColorMatrix类,可以创建一个4x5的矩阵来对图像进行色彩转换。对于灰度处理,可以设置矩阵如下: ``` ColorMatrix colorMatrix = new ColorMatrix(new float[] { 0.3f, 0.3...

    android-图像处理demo

    本教程将深入探讨如何使用Android的Bitmap类以及ColorMatrix来实现对图像颜色的处理。Bitmap是Android系统中用于存储和操作图像的基本类,而ColorMatrix则是一个强大的工具,可以用来改变图像的颜色、亮度、对比度等...

    android中图片色彩特效处理Demo

    在Android开发中,图片色彩特效处理是一个非常重要的领域,它涉及到图像处理算法和Android系统提供的图像API。这个"android中图片色彩特效处理Demo"旨在帮助开发者理解如何改变图片的色调、饱和度和亮度,从而创建出...

    Android色彩特效处理

    在Android平台上,色彩特效处理是开发移动应用时一个不可或缺的部分,尤其在图像编辑、相机滤镜或者用户界面设计中。Android提供了丰富的API和技术,让开发者能够实现各种复杂的色彩变换和特效。本文将深入探讨...

    Android开发画图功能并修饰

    美化功能则需要利用图像处理库,如Android的`ColorMatrix`或者第三方库如Picasso、 Glide等,它们提供了丰富的滤镜和效果。 例如,要实现浮雕效果,可以通过调整色彩矩阵来改变图像的灰度和对比度;而淡化效果则...

Global site tag (gtag.js) - Google Analytics