Android Matrix类以及ColorMatri

引自:http://www.chinabaike.com/t/37396/2014/0624/2556217.html

Android Matrix类以及ColorMatrix类详解

最近在系统学习了android的图像处理(在网上搜集了一些资料并自己编写了测试程序,做了整理),现在这里做一总结:

一、ColorMatrix类

ColorMatrix是一个5x4阶的矩阵 在下面表示为A,第一行表示R红色分量,第二行表示G绿色分量,第三行表示B蓝色分量,第四行表示透明度:

用一维数组的存储方式如下: [ a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t ],

颜色矩阵和颜色分量相乘之后得到新的颜色如下:

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; //透明度

颜色矩阵的第五列表示各个颜色的偏移量。

  

下面了解下ColorMatrix的常用API:

public void set(float[] src) 将src数组的值赋给颜色矩阵A

public final float[] getArray() 返回颜色矩阵A的具体数值,以一阶数组形式表示

public void setConcat(ColorMatrix matA,ColorMatrix matB) 将颜色矩阵matA和matB复合,相当与对图片进行matA矩阵处理再进行矩阵matB处理。

public void postConcat (ColorMatrix postmatrix) 若matA.postConcat(postmatrix)等价与 setConcat(postmatrix,matA)。

public void preConcat (ColorMatrix prematrix) 若matA.preConcat(prematrix)等价与 setConcat(matA,prematrix)。

public void setRotate (int axis, float degrees) 设置颜色分量旋转:axis==0旋转红色;axis==1对应绿色;axis==2对应蓝色,

源码如下:

/**

* Set the rotation on a color axis by the specified values.

* axis=0 correspond to a rotation around the RED color

* axis=1 correspond to a rotation around the GREEN color

* axis=2 correspond to a rotation around the BLUE color

*/

public void setRotate(int axis, float degrees) {

reset();

float radians = degrees * (float)Math.PI / 180;

float cosine = FloatMath.cos(radians);

float sine = FloatMath.sin(radians);

switch (axis) {

// Rotation around the red color

case 0:

mArray[6] = mArray[12] = cosine;

mArray[7] = sine;

mArray[11] = -sine;

break;

// Rotation around the green color

case 1:

mArray[0] = mArray[12] = cosine;

mArray[2] = -sine;

mArray[10] = sine;

break;

// Rotation around the blue color

case 2:

mArray[0] = mArray[6] = cosine;

mArray[1] = sine;

mArray[5] = -sine;

break;

default:

throw new RuntimeException();

}

}

public void setSaturation (float sat) 通过改变矩阵的值设置图像的饱和度 参数0对应灰色图像,1对应没改变

public void setScale (float rScale, float gScale, float bScale, float aScale) 设置矩阵的R,G,B,A等变量到对应的倍数。

对应的api为setScale(1,2,1,1);这个函数实际对应设置的是颜色矩阵对角线上的值。

下面的例子作出了对图像的一些处理,比较简单:

private void useColorMatrix(Canvas canvas,Paint paint) {

// TODO Auto-generated method stub

//清除画笔的颜色过滤

paint.setColorFilter(null);

cmatrix = new ColorMatrix();

cmatrix.set(carrycolor);

//cmatrix.reset();

//cmatrix.setSaturation(0F);

//cmatrix.setRotate(0, 100);

//cmatrix.setScale(2, 2, 2, 2);

//设置颜色矩阵过滤器

paint.setColorFilter(new ColorMatrixColorFilter(cmatrix));

canvas.drawBitmap(bitmap, 0,0, paint);

}

二、Matrix类详解

Matrix类是一个3x3的位置坐标矩阵,该类对矩阵进行初始化必须通过reset函数或者set...等方法,

图形的放大缩小,移动,旋转,透视,扭曲这些效果都可以用该此矩阵来完成。位置矩阵A的第一行控制X坐标,第二行控制y坐标第三行控制Z坐标。

这个矩阵的作用是对坐标x,y进行变换计算结果如下:

x‘=a*x+b*y+c

y‘=d*x+e*y+f

由上面的公式可以看出c,f分别控制x,和y位置的偏移量,a和e控制X,与y坐标倍数的变化,所以

x放大a倍,y放大b倍,

矩阵就是:,

x方向的平移量为△x,y方向的平移量为△y,那么,点P(x,y)的坐标为:

x = x0 + △x

y = y0 + △y

采用矩阵表达上述如下:

先移动再放大用的是矩阵的乘法如A*B。

图像的旋转稍微复杂:现设点P0(x0, y0)绕原点旋转θ角后的对应点为P(x, y)。通过使用向量,我们得到如下,r为旋转半径:

x0 = r cosα

y0 = r sinα

x = r cos(α+θ) = x0 cosθ - y0 sinθ (三角函数展开然后变量替换)

y = r sin(α+θ) = x0 sinθ + y0 cosθ

于是我们得到矩阵:

图像的镜像,分为2种:水平镜像、垂直镜像。先介绍如何实现垂直镜像,什么是垂直镜像就不详细说明。图像的垂直镜像变化也可以用矩阵变化的表示,

设点P0(x0 ,y0 )进行镜像后的对应点为P(x ,y ),图像的高度为fHeight,宽度为fWidth,原图像中的P0(x0 ,y0 )经过垂直镜像后的坐标变为(x0 ,2*fHeight- y0);

x = x0 垂直镜像后x坐标不变

y = fHeight – y0 垂直镜像后相当与先将图像绕x轴旋转180度,再将图像向下平移两个图像的高度,所以先y=-y0;然后再加2倍高度

推导出相应的矩阵是:

final float f[] = {1.0F,0.0F,0.0F,0.0F,-1.0F,120.0F,0.0F,0.0F,1.0F};

Matrix matrix = new Matrix();

matrix.setValues(f);

代码如下:

@Override

protected void onDraw(Canvas canvas) {

// TODO Auto-generated method stub

super.onDraw(canvas);

Paint paint = mPaint;

//useColorMatrix(canvas,paint);

matrix = new Matrix();

matrix.setValues(carrypos);

paint.setColorFilter(null);

canvas.drawBitmap(bitmap,matrix,paint);// you can setColorFilter(null);

carrypos[5] = 2*bitmap.getHeight();//设置y坐标移动

carrypos[4] = -1;//设置绕x轴转180度

matrix.setValues(carrypos);

canvas.drawBitmap(bitmap, matrix, paint);

}

按照上述方法运行后的结果:

实际上,使用下面的方式也可以实现垂直镜像:

Matrix matrix = new Matrix();

matrix.setScale (1.0,-1.0);

matrix.postTraslate(0,2* fHeight);

Matrix学习——图像的复合变化

如果图像围绕着某个点P(a,b)旋转,则先要将坐标系平移到该点,再进行旋转,然后将旋转后的图像平移回到原来的坐标原点。

我们需要3步:

1. 平移——将坐标系平移到点P(a,b);

2. 旋转——以原点为中心旋转图像;

3. 平移——将旋转后的图像平移回到原来的坐标原点;

相比较前面说的图像的几何变化(基本的图像几何变化),这里需要平移——旋转——平移,这种需要多种图像的几何变化就叫做图像的复合变化。

设对给定的图像依次进行了基本变化F1、F2、F3…..、Fn,它们的变化矩阵分别为T1、T2、T3…..、Tn,图像复合变化的矩阵T可以表示为:T = TnTn-1…T1。

按照上面的原则,围绕着某个点(a,b)旋转θ的变化矩阵序列是:

按照上面的公式,我们列举一个简单的例子:围绕(100,100)旋转30度(sin 30 = 0.5 ,cos 30 = 0.866)

float f[]= { 0.866F, -0.5F, 63.4F,0.5F, 0.866F,-36.6F,0.0F, 0.0F, 1.0F };

matrix = new Matrix();

matrix.setValues(f);

旋转后的图像如下:

Android为我们提供了更加简单的方法,如下:

Matrix matrix = new Matrix();

matrix.setRotate(30,100,100);

矩阵运行后的实际结果:

与我们前面通过公式获取得到的矩阵完全一样。

在这里我们提供另外一种方法,也可以达到同样的效果:

float a = 100.0F,b = 100.0F;

matrix = new Matrix();

matrix.setTranslate(a,b);

matrix.preRotate(30);

matrix.preTranslate(-a,-b); //等价与matrix=matrix*T(移动相应距离的矩阵) post...(把pre的乘积因子相交换)

Matrix学习——错切变换

什么是图像的错切变换(Shear transformation)?我们还是直接看图片错切变换后是的效果:

上图是设置了x向量的第二个参数为0.5F 即x=x0+0.5y0 所以x随y的增大而成斜率为0.5的线性变化。

代码如下:

private float[]carrypos2 ={1,0,100,

0,1,100,

0,0,1};//z no change

float[] test01 = carrypos2;

test01[1] = 0.5F;

matrix.setValues(test01);

canvas.drawBitmap(bitmap, matrix, paint);

也可以這樣寫:

对图像的错切变换做个总结:

x = x0 + b*y0;

y = d*x0 + y0;

这里再次给大家介绍一个需要注意的地方:

通过以上,我们发现Matrix的setXXXX()函数,在调用时调用了一次reset(),这个在复合变换时需要注意。

Matrix学习——对称变换(反射)

什么是对称变换?具体的理论就不详细说明了,图像的镜像就是对称变换中的一种。

利用上面的总结做个具体的例子,产生与直线y= – x对称的反射图形,代码片段如下:

当前矩阵输出是:

图像变换的效果如下:

附:三角函数公式

两角和公式

sin(a+b)=sinacosb+cosasinb

sin(a-b)=sinacosb-sinbcosa 

cos(a+b)=cosacosb-sinasinb

cos(a-b)=cosacosb+sinasinb

tan(a+b)=(tana+tanb)/(1-tanatanb)

tan(a-b)=(tana-tanb)/(1+tanatanb)

cot(a+b)=(cotacotb-1)/(cotb+cota) 

cot(a-b)=(cotacotb+1)/(cotb-cota)

倍角公式

tan2a=2tana/[1-(tana)^2]

cos2a=(cosa)^2-(sina)^2=2(cosa)^2 -1=1-2(sina)^2

sin2a=2sina*cosa

半角公式

sin(a/2)=√((1-cosa)/2) sin(a/2)=-√((1-cosa)/2)

cos(a/2)=√((1+cosa)/2) cos(a/2)=-√((1+cosa)/2)

tan(a/2)=√((1-cosa)/((1+cosa)) tan(a/2)=-√((1-cosa)/((1+cosa))

cot(a/2)=√((1+cosa)/((1-cosa)) cot(a/2)=-√((1+cosa)/((1-cosa)) 

tan(a/2)=(1-cosa)/sina=sina/(1+cosa)

和差化积

2sinacosb=sin(a+b)+sin(a-b)

2cosasinb=sin(a+b)-sin(a-b) )

2cosacosb=cos(a+b)-sin(a-b)

-2sinasinb=cos(a+b)-cos(a-b)

sina+sinb=2sin((a+b)/2)cos((a-b)/2

cosa+cosb=2cos((a+b)/2)sin((a-b)/2)

tana+tanb=sin(a+b)/cosacosb

积化和差公式

sin(a)sin(b)=-1/2*[cos(a+b)-cos(a-b)]

cos(a)cos(b)=1/2*[cos(a+b)+cos(a-b)]

sin(a)cos(b)=1/2*[sin(a+b)+sin(a-b)]

诱导公式

sin(-a)=-sin(a)

cos(-a)=cos(a)

sin(pi/2-a)=cos(a)

cos(pi/2-a)=sin(a)

sin(pi/2+a)=cos(a)

cos(pi/2+a)=-sin(a)

sin(pi-a)=sin(a)

cos(pi-a)=-cos(a)

sin(pi+a)=-sin(a)

cos(pi+a)=-cos(a)

tga=tana=sina/cosa

万能公式

sin(a)= (2tan(a/2))/(1+tan^2(a/2))

cos(a)= (1-tan^2(a/2))/(1+tan^2(a/2))

tan(a)= (2tan(a/2))/(1-tan^2(a/2))

其它公式

a*sin(a)+b*cos(a)=sqrt(a^2+b^2)sin(a+c) [其中,tan(c)=b/a]

a*sin(a)-b*cos(a)=sqrt(a^2+b^2)cos(a-c) [其中,tan(c)=a/b]

1+sin(a)=(sin(a/2)+cos(a/2))^2

1-sin(a)=(sin(a/2)-cos(a/2))^2

其他非重点三角函数

csc(a)=1/sin(a)

sec(a)=1/cos(a)

双曲函数

sinh(a)=(e^a-e^(-a))/2

cosh(a)=(e^a+e^(-a))/2

tgh(a)=sinh(a)/cosh(a)

时间: 2024-11-02 10:35:21

Android Matrix类以及ColorMatri的相关文章

Android Matrix图像变换处理

Canvas类中drawBitmap(Bitmap bitmap, Matrix matrix, Paint paint)方法中有个参数类型是Matrix,从字面上理解是矩阵的意思,而实际上它也确实是个3x3的矩阵.Matrix在Android中的主要作用是图像变换,如平移.旋转.缩放.扭曲等. 关于图像如何通过矩阵进行变化可参考这篇文章图像处理-关于像素坐标矩阵变换(平移,旋转,缩放,错切) Matrix内部通过维护一个float[9]的数组来构成3x3矩阵的形式,而实际上所有的变换方法说到底

Android中的Matrix类介绍

Matrix顾名思义就是大学的线性代数中的矩阵,关于矩阵的基本知识和加减乘除运算这里不再赘述. Android中的Matrix类是一个比较简单的3x3的3阶矩阵,结构如下: float matrix = {MSCALE_X, MSKEW_X, MTRANS_X, MSKEW_Y, MSCALE_Y, MTRANS_Y, MPERSP_0, MPERSP_1, MPERSP_2 }; 结构如上:其中 MSCALE_X和MSCALE_Y分别是控制X轴和Y轴方向的缩放,MSKEW_X和MSKEW_Y是

Android的Matrix类简介

Matrix: 图片的处理需要使用到Matrix类,Matrix是一个3 x 3的矩阵,他对图片的处理分为四个基本类型: 1.Translate————平移变换 2.Scale————缩放变换 3.Rotate————旋转变换 4.Skew————错切变换 操作方式: set(用于设置Matrix中的值). pre(先乘,相当于矩阵中的右乘), post(后乘,根据矩阵的原理,相当于左乘). 除了translate,旋转.缩放和倾斜都可以指定中心点.如果不指定,默认情况下,是围绕(0,0)点来进

Android Matrix(转)

Matrix的数学原理 平移变换 旋转变换 缩放变换 错切变换 对称变换 代码验证 Matrix的数学原理 在Android中,如果你用Matrix进行过图像处理,那么一定知道Matrix这个类.Android中的Matrix是一个3 x 3的矩阵,其内容如下: Matrix的对图像的处理可分为四类基本变换: Translate           平移变换 Rotate                旋转变换 Scale                  缩放变换 Skew          

android 小说类源码制作教程源码下载

自己闲着没事制作了个小说软件用来自己看全本/连载小说, 翻页,字体大小,目录,自动更新 具体效果如下:奉献给大家下载查看... 下载APK效果查看地址: http://yun.baidu.com/s/1gdknYyJ 源码下载地址: http://download.csdn.net/detail/ainibaifenbai/7575817 android 小说类源码制作教程源码下载,布布扣,bubuko.com

Android Activity类讲解(一)

--by CY[[email protected]] 1.protected void onCreate(Bundle savedInstanceState) { throw new RuntimeException("Stub!"); } 当创建一个Activity时,系统会自动调用onCreate方法来完成创建工作.该创建工作包括布局,监听器的绑定等. 首先说一下Bundle 这个类,Bundle是一个键值对,跟Map类似,两个Activity之间的通信可以用Bundle类来实现.

android异步类AsyncTask的简单使用

Android为了降低这个开发难度,提供了AsyncTask.AsyncTask就是一个封装过的后台任务类,顾名思义就是异步任务,更通俗地说就是一个执行后台任务的线程 而且他还会自动通知主线程更新UI 优点: 结构清晰,容易理解. 缺点 代码量稍大 下面直接看代码 1 private class AsyncLogin extends AsyncTask<Void,Integer,Boolean>{ 2 private EditText passwordEdit; 3 private EditT

Android图像格式类及图像转换方法

Android图像格式类及图像转换方法介绍 一款软件的开发和图像密切相关,特别是移动应用程序,在视觉效果等方面是至关重要的,因为这直接关系 到用户的体验效果.在Android程序开发的过程中,了解存在哪些图像格式类(ImageFormat.PixelFormat及BitmapConfig等)及图像(JPG.PNG及 BMP等)的转换方法,对以后的开发多多少少会有些帮助. 关于图像格式类,介绍以下三个:ImageFormat.PixelFormat及BitmapConfig. 1.ImageFor

Android基类设计方法详解

1 为什么要设计基类 为什么要给程序设计基类呢?主要是出于2个原因,一是方便代码编写,减少重复代码和冗余逻辑,优化代码:二是优化程序架构,降低耦合度,方便拓展.修改. ok,编写代码是程序员的第一步,那么第二步就是要编写高质量的代码,代码能实现功能是一方面,写的优美则是另一方面,这也是我们所有攻城狮们应该追求的境界. 2 设计基类的基本思路 那么,哪些东西我们需要抽象到基类中呢? 2.1 重复的代码:如果一个逻辑是大多数子类都需要使用的 2.2 臭而长的代码:典型的findviewbyid.To