Android Matrix的set\pre\post方法的区别和使用

Matrix包含一个3X3的矩阵,专门用于图像变换匹配
该篇文章更多的是区分set\pre\post的区别并且用例子演示,更多有关系统的讲解矩阵,可以参考以下文章:

  1. 如何计算矩阵乘法
  2. android matrix 最全方法详解与进阶(完整篇)
  3. Android Matrix 最全方法详解与进阶
  4. 1-4 Canvas 对绘制的辅助 clipXXX() 和 Matrix
  5. 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,让同学们更好清晰了解生效距离


Matrix例子

先pre-后post

matrix.preScale(2,2);
matrix.postTranslate(100, 100);
先pre-后post的效果图

解释:pre是放大,post是移动,先放大两倍,后移动(100,100)

先post-后pre

matrix.postScale(2,2);
matrix.preTranslate(100, 100);
先post-后pre的效果图

解释: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的效果图

解释:注意第三句代码是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的坐标点进行矩阵变换的

好的那么基本就到了这里了,作者基本已经弄懂了,同学们没弄懂可以在下面留言!弄懂了点个赞谢谢!

你可能感兴趣的:(Android Matrix的set\pre\post方法的区别和使用)