Matrix矩阵介绍

在Android中,对图片的处理需要使用到Matrix类,Matrix是一个3 x 3的矩阵,内部就是个一维数组,内部有9个元素,可以通过setValues(float[])进行初始化,通过getValues(float[])把拿到的矩阵值赋给传入的数组。

源码中的介绍就一句话:The Matrix class holds a 3x3 matrix for transforming改变 coordinates坐标.

其具体坐标对应的属性为:
{MSCALE_X,    MSKEW_X,    MTRANS_X,
 MSKEW_Y,     MSCALE_Y,   MTRANS_Y,
 MPERSP_0,    MPERSP_1,    MPERSP_2}

各个值的含义为
  • MSCALE_X = 0;     X缩放
  • MSKEW_X  = 1;     X错切
  • MTRANS_X = 2;    X移动
  • MSKEW_Y  = 3;     Y错切
  • MSCALE_Y = 4;      Y缩放
  • MTRANS_Y = 5;     Y移动
  • MPERSP_0 = 6;      透视,透视就是观察的角度变化了。导致投射到平面上的二维图像变化了。
  • MPERSP_1 = 7;      透视
  • MPERSP_2 = 8;      透视

从字面上理解,矩阵中的MSCALE用于处理缩放变换,MSKEW用于处理错切变换,MTRANS用于处理平移变换,MPERSP用于处理透视变换。实际中当然不能完全按照字面上的说法去理解Matrix。同时,在Android的文档中,未见到用Matrix进行透视变换的相关说明,所以本文也不讨论这方面的问题。

在Canvas上绘制图形时既可使用Matrix,也可使用ColorMatrix来改变在Canvas对象上绘制的Paint对象。

关于错切

错切变换,在数学上又称为Shear mapping(可译为“剪切变换”)或者Transvection(缩并),它是一种比较特殊的线性变换。
错切变换的效果就是让所有点的x坐标(或者y坐标)保持不变,而对应的y坐标(或者x坐标)则按比例发生平移,且平移的大小和该点到x轴(或y轴)的垂直距离成正比。错切变换,属于等面积变换,即一个形状在错切变换的前后,其面积是相等的。

下图一:各点的y坐标保持不变,但其x坐标则按比例发生了平移,这种情况叫水平错切。
下图二:各点的x坐标保持不变,但其y坐标则按比例发生了平移,这种情况叫垂直错切。
 

操作示例

获取x方向缩放比例:
matrix.getValues(matrixValues);
return matrixValues[Matrix.MSCALE_X];

移动与缩放
Matrix matrix = new Matrix();
matrix.setValues(new float[] {
        1, 0, 0,
        0, 1, 0,
        0, 0, 1
});
x'=1x+0y+0z(x坐标)
y'=0x+1y+0z(y坐标)
z'=0x+0y+1z(目前没用到)
如果第一行改为(0.5f,0,0),那么图像在x轴上将图像缩小到50%;如果第二行改为(0,2,0),那么图像在y轴上将图像放大到2倍;
如果第一行改为(1,0,100),那么图像在x轴上向右移动100像素;如果第二行改为(0,1,-100),那么图像在y轴上向上移动100像素;

常用API

构造函数
  • public Matrix():Create an identity matrix 单位矩阵
  • public Matrix(Matrix src):根据提供的矩阵创建一个新的矩阵。Create a matrix that is a (deep) copy of src
矩阵的值
  • set(Matrix src):复制。(deep) copy the src matrix into this matrix.
  • setValues(float[]):用指定的值进行初始化
  • getValues(float[]):通过把拿到的矩阵值赋给传入的数组。Copy 9 values from the matrix into the array.
  • reset:重置矩阵为单位矩阵。Set the matrix to identity
  • invert(Matrix inverse):反转、倒置。如果能反转就返回true并将反转后的值写入inverse,否则返回false。【当前矩阵*inverse=单位矩阵】
控制图片变换:
  • setTranslate(float dx,float dy):控制Matrix进行平移。右下为正
  • setSkew(float kx,float ky):控制Matrix以(0,0)为中心进行错切,kx、ky为X、Y方向上的比例
  • setRotate(float degrees):控制Matrix以(0,0)为中心进行depress角度的旋转,顺时针为正
  • setSinCos(float sinValue, float cosValue):不指定旋转角度,而是指定旋转角度对应的sin和cos值,比如,向右旋转90°时,对应的sin值为sin90°=1,对应的con值为cos90°=0。不指定中心点时的中心点为(0,0)。Set the matrix to rotate by the specified指定的 sine and cosine values, with a pivot中心点 point at (px, py).
  • setScale(float sx,float sy):设置Matrix以(0,0)为中心进行缩放,sx、sy为X、Y方向上的缩放比例。如果为负,那么会将该图像绘制到坐标系统的负值空间
       说明
    • 除平移变换外,旋转变换、缩放变换和错切变换都可以围绕一个中心点来进行,如果不指定,在默认情况下是围绕(0, 0)来进行相应的变换的。
    • 以上的set方法(除了setSinCos方法),均有对应的post和pre方法。其中pre表示在队头插入一个方法(相当于矩阵中的右乘),post表示在队尾插入一个方法(相当于矩阵中的左乘),而set表示把当前队列清空,并且总是位于队列的最中间位置。
    • 当执行了一次set后,前面所有的set、pre、post都将清空,后续的pre方法总是插入到set前部的队列的最前面,post方法总是插入到set后部的队列的最后面。
    • Matrix调用一系列set、pre、post方法时,可视为将这些方法插入到一个队列,最后按照队列中从头至尾的顺序调用执行。
其他API
  • isIdentity():判断是否是单位矩阵
  • isAffine():判断是否是仿射矩阵,只要最后一行是0,0,1则是仿射矩阵。
  • rectStaysRect():判断该矩阵是否可以将一个矩形依然变换为一个矩形。当矩阵是单位矩阵,或者只进行平移,缩放,以及旋转90度的倍数的时候,返回true。Returns true if will map a rectangle to another rectangle.
  • setConcat(Matrix a, Matrix b):将当前matrix的值变为a和b的乘积。Set the matrix to the concatenation关联 of the two specified matrices and return true.

Matrix方法表

方法类别    相关API                                                         摘要
基本方法    equals hashCode toString toShortString 比较、 获取哈希值、 转换为字符串
数值操作    set reset setValues getValues 设置、 重置、 设置数值、 获取数值
设置(set)    setConcat setRotate setScale setSkew setTranslate    设置变换
前乘(pre)    preConcat preRotate preScale preSkew preTranslate    前乘变换
后乘(post)   postConcat postRotate postScale postSkew postTranslate 后乘变换
数值计算    mapPoints mapRadius mapRect mapVectors 计算变换后的数值
特殊方法    setPolyToPoly setRectToRect rectStaysRect setSinCos 一些特殊操作
矩阵相关    invert isAffine isIdentity 求逆矩阵、 是否为仿射矩阵、 是否为单位矩阵 …


最新文章

  1. C语言的内存分配
  2. noip2008-t3
  3. JAVA 加减乘除
  4. Java小bug
  5. mysql update时报错You are using safe update mode
  6. 银行ATM机工作流程模拟编程(代码)
  7. Windows Self Signed Driver
  8. eclipse开发android程序常见问题解决办法
  9. Android-adb shell 读取手机系统文件
  10. 利用maven中resources插件的copy-resources目标进行资源copy和过滤
  11. docker 现实---中小企业docker环境结构(五)
  12. asp.net如何删除文件夹及文件内容操作
  13. Python爬虫入门:Urllib库的高级使用
  14. LuoguP3701 「伪模板」主席树
  15. 访问了一次百度网页,你都经历了什么?https及tcp协议揭秘
  16. css3实现水平垂直居中
  17. ES6 对对象的扩展
  18. Shellcode入门
  19. Word批量删除所有书签
  20. 812. Largest Triangle Area

热门文章

  1. Vibrator震动
  2. 转:使用python的Flask实现一个RESTful API服务器端
  3. HDU 6183 Color it
  4. Python之路【第六篇】:模块与包
  5. Xamarin.Forms教程开发的Xcode的下载安装
  6. 【模式匹配】更快的Boyer
  7. 【BZOJ 4169】 4169: Lmc的游戏 (树形DP)
  8. luoguP4284 [SHOI2014]概率充电器 概率期望树形DP
  9. POJ 1509 Glass Beads 后缀自动机 模板 字符串的最小表示
  10. bzoj 3437: 小P的牧场 -- 斜率优化