Android 变形矩阵——Matrix

对于图像的色彩处理,Android系统提供了ColorMatrix颜色矩阵来帮助我们进行图像处理。而对于图像的图形变化,Android系统也是通过来进行处理的,每个像素点都表达了其坐标的X、Y信息。Android的图形变换矩阵是一个3x3的矩阵,如图(1)所示。

 当使用变换矩阵去处理每一个像素点的时候,与颜色矩阵的矩阵乘法一样,计算公式如下所示。

        X1 = a * X + b * Y + c
        Y1 = d * X + e * Y + f
        l = g * X + h * Y + i  

 通常情况下,会让g=h=0,i=1,这是使 l = g * x + h *y + i恒成立。因此,只需要关注上面几个参数就可以了。

与色彩变换矩阵的初始矩阵一样,图像变换矩阵也有一个初始矩阵。很明显,就是对直角元素a、e、i我1,其他元素我0的矩阵,如图(2)所示。

图像的变化处理通常包含以下四类基本变化

● Translate——平移变换

● Rotate——选择变换

● Scale——缩放变换

● Skew——错切变换

▶ 平移变换

平移变换的坐标值变换过程如图(3)所示,即将每个像素点都进行平移变换。

当从p(X0,Y0)平移到p(X,Y),坐标值发送了如下所示的变换

            X = X0 + △X 
            Y = Y0 + △Y      

如果写成矩阵形式就是如图(4)所示。

通过技计算可发现如下等式。

            X = X0 + △X 
            Y = Y0 + △Y      

这也就是前面所说的实现平移过程的平移公式,图(4)所示矩阵也就是平移变换矩阵。

▶ 旋转变换

选择变换即指一个点围绕一个旋转中心旋转到一个新的点,如图(5)所示。

当从p(x0,y0),以坐标原点为旋转中心旋转到p(x ,y)点时,可以将点的坐标都表达成OP与X轴正方向夹角的函数表达式,如下所示。

x0 = r cosα

y0 = r sinα

x = r cos(α + θ)= r cosα cosθ - r sinα sinθ = x0cosθ - y0sinθ

y = r sin(α + θ)= r sinα cosθ - r cosα sinθ = x0cosθ + y0sinθ

如果写错矩阵形式就是如图(6)所示。

通过计算,可以还原以上公式,图(6)所示矩阵也及时旋转变换矩阵。

前面是以坐标原点为旋转中心的旋转变换,如果以任意点O为旋转中心来进行旋转变换,通常需要以下三个步骤。

● 将坐标原点平移到O点。

● 使用前面说的以坐标原点为中心的旋转方法进行旋转变换。

● 将坐标原点还原。

通过上面三个步骤,实现了任意点为旋转中心的旋转变换。

▶ 缩放变换

一个像素点是不存在缩放概念的,但是由于图像是由很多个像素点组成的,如果将每个点的坐标都进行相同比例的缩放,最终就会形成整个图像缩放的效果,缩放效果的计算公式如下。

x = K1 * x0

y = K2 * y0

如果写成矩阵形式,就如图(7)所示。

通过计算,就可以还原以上等式,因此图(7)所示矩阵即为缩放变换矩阵。

▶ 错切变换

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

错切变换通常包好两种——水平错切和垂直错切,分别如图(8)、图(9)所示。

错切变换的计算公式如下所示。

x = x0 + K1 * Y0

y = K2 * x0 * y0

如果写成矩阵形式,就如果(10)所示。

通过计算,就可以还原到以上等式。因此图(10)所示矩阵即为错切变换矩阵。

有上面的分析可以发现,这个3*3的矩阵与颜色变换矩阵一样,每个位置的元素所表示的功能是有规律的,总结规律如图(11)所示。

可以发现,A、B、C、D、E、F、这六个矩阵元素分别对应一下变换。

● A和E控制Scale——缩放变换

● B和D控制Skew——错切变换

● C和F控制Trans——平移变换

● A、B、C、D共同控制Rotate——选择变换

在了解了矩阵变换规律后,通过类似色彩矩阵中模拟矩阵的例子来模拟一下变形矩阵。整个代码与模拟颜色矩阵所使用的代码基本一致。在图形变换矩阵中,同样通过一个一维数组来模拟矩阵,并通过setValues()方法将一个一维数组转换为图形变换矩阵,代码如下所示。

        private float[] mImageMatrix = new float[9];        
        Matrix matrix = new Matrix();
        matrix.setValues(mImageMatrix );

当获得了变换矩阵后,就可以通过以下代码将一个图像一这个变换矩阵的形式绘制出来。

        canvas.drawBitmap(bitmap,matrix,null);

运行时程序后,初始界面如图(12)所示。

                                                                                    (12)模拟变形矩阵

当然,与色彩矩阵一样,Android系统同样提供了一些API来简化矩阵的运算。我们不必每次都去设置矩阵的每一个元素值。Android中使用Matri类来封装矩阵,并提供以下几个操作方法来实现上面的四种变换方式。

● matri X .setRotate()——选择变换

● matri X .setTranslate()——平移变换

● matri X .setScale()——缩放变换

● matri X .setSkew()——错切变换

● pre()和post()——提供矩阵的前乘后乘运算

Matri类的set方法会重置矩阵所有值,而post和pre方法不会,这两个方法常用来实现矩阵的混合作用。不过要注意的是,矩阵运算不能满足变换率,所以矩阵乘法的前乘和后乘是两种不同的运算方式。举个例子来说,比如需要实现以下效果。

● 先平移到(300,100)

● 在选择45度

● 最后平移到(200,200)

如果使用后乘算法,表示当当前矩阵上参数代表的矩阵,带入如下所示。

        matrix.setRotate(45);
        matrix.postTranslate(200,200);

如果使用前乘运算,表示参数代表的矩阵乘上当前矩阵,代码如下所示。

        matrix.setTranslate(200,200);
        matrix.preRotate(45);

 

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值