Matrix包含一个3X3的矩阵,专门用于图像变换匹配
该篇文章更多的是区分set\pre\post的区别并且用例子演示,更多有关系统的讲解矩阵,可以参考以下文章:
- 如何计算矩阵乘法
- android matrix 最全方法详解与进阶(完整篇)
- Android Matrix 最全方法详解与进阶
- 1-4 Canvas 对绘制的辅助 clipXXX() 和 Matrix
- Android中的Matrix(矩阵) - itlgl - 博客园 (cnblogs.com)
好的那么让我们直接进入主题,Matrix提供了四种操作:
操作 | 注释 |
---|---|
translate | 平移 |
rotate | 旋转 |
scale | 缩放 |
skew | 错切 |
每种操作都有3种方式
方式 | 注释 |
---|---|
pre | 在队列最前面插入 |
post | 在队列最后面追加 |
set | 先清空队列在添加 |
下面通过例子具体说明,具体例子下载地址:
ImageingStudy/MatrixActivity.java at master · zhongjhATC/ImageingStudy (github.com)
Matrix例子如图,每条线的间距是50dp,让同学们更好清晰了解生效距离
先pre-后post
matrix.preScale(2,2);
matrix.postTranslate(100, 100);
解释:pre是放大,post是移动,先放大两倍,后移动(100,100)
先post-后pre
matrix.postScale(2,2);
matrix.preTranslate(100, 100);
解释:pre 先移动,post是放大。所以是先平移到(100,100),再放大一倍。 明明跟上面例子一样数值。为啥差距这么大,原因是执行顺序不同导致的,因为先移动到(100,100)后,再进行放大是从整个移动后的画布放大的。所以到达了(200,200)坐标处
多次转换
matrix.preScale(2f,2f);
matrix.preTranslate(50, 50);
matrix.postScale(0.5f, 0.5f);
matrix.postTranslate(10, 10);
解释:执行顺序是
preTranslate(50, 50)
——》 preScale(2f,2f)
——》postScale(0.5f, 0.5f)
——》postTranslate(10, 10)
细心的同学会发现为什么先执行preTranslate再执行preScale呢,原因是pre是执行在队列最前面
setScale
matrix.postTranslate(50, 50);
matrix.preScale(0.5f, 0.5f);
matrix.setScale(1f, 1f);
matrix.postScale(3f, 3f);
matrix.preTranslate(10, 10);
解释:注意第三句代码是setScale,也就是说,不管前面执行多少句转换代码都不起作用了,所以执行顺序只有这几句:
preTranslate(10, 10)
——》 setScale(1f, 1f)
——》 postScale(3f, 3f)
注意哦,pre仍然是在set队列前面
负数转换
···
postScale(-1, -1);
postTranslate(100,100);
···
这是一种特殊的缩放变换。X为负数,则表示以X轴翻转后,再进行缩放。
注意: 没有Translate,只有matrix.setScale(-1,1)。 图像会翻转到X轴返方向。会看不到图像。
Translate 最好用 postTranslate 。 如果用了setScale 和 preTranslate ,是不会看到图像的。
理解:因为是preTranslate,会将图像先平移,距离X轴一段距离。然后再将图像沿X轴翻转。然后再放大(整体放大,包括刚才的平移的距离。)导致图像离X的负半轴更远。
Matrix.mapRect()理解
有时候我们不针对View或者ImageView进行整个的Matrix处理,可能会对View里面的某块RectF进行处理,那么就需要这个了,让我们直接看例子吧!
/**
* 缩放
*/
public void scaleBitmap(View view) {
RectF r = new RectF(0, 0, imageView.getWidth(), imageView.getHeight());
Log.d("MatrixMapRectActivity", "-r.left = " + r.left + ", right = " + r.right + ", top = "
+ r.top + ", bottom = " + r.bottom);
Matrix matrix = new Matrix();
matrix.setScale(2,3);
matrix.mapRect(r);
// 可以看到宽度涨了2倍,高度涨了三倍
Log.d("MatrixMapRectActivity", "-r.left = " + r.left + ", right = " + r.right + ", top = "
+ r.top + ", bottom = " + r.bottom);
imageView.setImageMatrix(matrix);
}
上面这段代码log如下:
-r.left = 0, right = 100.0, top = 0.0, bottom = 100.0
-r.left = 0, right = 200.0, top = 0.0, bottom = 300.0
所以mapRect是单独对RectF的坐标点进行矩阵变换的