官方文档镇楼
https://developer.android.com/reference/android/graphics/Matrix.html
The Matrix class holds a 3x3 matrix for transforming coordinates.
Matrix是一个用于坐标变换的3*3矩阵
若一矩阵的列数与另一矩阵的行数相等,则可定义这两个矩阵的乘积。如 A 是 m×n 矩阵和 B 是 n×p矩阵,它们是乘积 AB 是一个 m×p 矩阵,其中
(AB)[i, j] = A[i, 1] * B[1, j] + A[i, 2] * B[2, j] + … + A[i, n] * B[n, j] 对所有 i 及 j。
矩阵左乘相当于行变换,例如对于矩阵A:
矩阵右乘相当于列变换,例如对于矩阵A,如果想让其第一列和第二列进行变换,则只需为其右乘一个矩阵C:
在Android中Matrix由9个float值构成,是一个3*3的矩阵,如下图:
由上文可知,如果我们将matrix矩阵的值设置为:
public void rotate1(){
ImageView iv_image1 = (ImageView) findViewById(R.id.iv_rotate1);
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.filter_0, new BitmapFactory.Options());
iv_image1.setImageBitmap(bitmap);
iv_image1.setScaleType(ScaleType.MATRIX);
Matrix matrix_rotate1 = new Matrix();
float[] rotate1s = new float[]{0.0f,-1.0f,0.0f,
1.0f,0.0f,0.0f,
0.0f,0.0f,1.0f};
matrix_rotate1.setValues(rotate1s);
iv_image1.setImageMatrix(matrix_rotate1);
}
运行结果:
我们并没有看到旋转90°后的图片,这是因为,图片在以(0,0)为中心顺时针旋转90°后已经出了空间的范围,因此,我们已经看不到旋转后的图片。
那么如何以图片中心进行旋转呢,我们可以这样想,图片以(0,0)为中心顺时针旋转90°后再沿x轴正方向平移一段距离即可。这里需要注意的是平移的距离,答案应该是图片的高度减1(这个应该不难想到)。代码如下:
public void rotate2(){
ImageView iv_image2 = (ImageView)findViewById(R.id.iv_rotate2);
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.filter_0, new BitmapFactory.Options());
iv_image2.setImageBitmap(bitmap);
iv_image2.setScaleType(ScaleType.MATRIX);
Matrix matrix_rotate2 = new Matrix();
float[] rotates2 = new float[]{0.0f,-1.0f,bitmap.getHeight()-1.0f,
1.0f,0.0f,0.0f,
0.0f,0.0f,1.0f};
matrix_rotate2.setValues(rotates2);
iv_image2.setImageMatrix(matrix_rotate2);
}
运行结果:
其实旋转中已经涉及到了平移变换,只需对translateX,translateY进行赋值即可,需要注意的是这两个值代表的是平移量而非平移的坐标。另外平移是不可以设置中心点的。
public void translate(){
ImageView iv_translate = (ImageView)findViewById(R.id.iv_translate);
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.filter_0, new BitmapFactory.Options());
iv_translate.setImageBitmap(bitmap);
iv_translate.setScaleType(ScaleType.MATRIX);
Matrix matrix_translate = new Matrix();
float[] translates = new float[]{1.0f,0.0f,200.0f,
0.0f,1.0f,0.0f,
0.0f,0.0f,1.0f};
matrix_translate.setValues(translates);
iv_translate.setImageMatrix(matrix_translate);;
}
运行结果:
看到这里我们应该很清楚了,要想实现缩放效果,只需对scale值进行赋值即可,1代表不缩放,2代表缩放为原先的1/2,以此类推,默认(0,0)为中心点。注意:(0,0)表示图片的左上角坐标而非屏幕原点。
public void scale(){
ImageView iv_scale = (ImageView)findViewById(R.id.iv_scale);
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.filter_0, new BitmapFactory.Options());
iv_scale.setImageBitmap(bitmap);
iv_scale.setScaleType(ScaleType.MATRIX);
Matrix matrix_scale = new Matrix();
float[] scales = new float[]{1.0f,0.0f,0.0f,
0.0f,1.0f,0.0f,
0.0f,0.0f,2.0f};
matrix_scale.setValues(scales);
iv_scale.setImageMatrix(matrix_scale);
}
运行结果:
当然也可以设置按照某一中心点坐标进行缩放。这个下文会讲到。
上文我们从矩阵变换的角度讲解了,图片的坐标变换。其实安卓一已经为我们封装好了相关运算,我们只需调用相应的api即可。接下来会讲解这些api的用法和注意事项。
Matrix的操作,总共分为translate(平移),rotate(旋转),scale(缩放)和skew(倾斜)四种,每一种变换在Android的API里都提供了set, post和pre三种操作方式,除了translate,其他三种操作都可以指定中心点。
set是直接设置Matrix的值,每次set一次,整个Matrix的数组都会变掉。
post是后乘,当前的矩阵乘以参数给出的矩阵。可以连续多次使用post,来完成所需的整个变换。
包括:
- setRotate(float degrees) degrees为旋转的度数,正为顺时针,默认以(0,0)为旋转中心
- setRotate(float degrees, float px, float py) px,py为旋转中心坐标
- setScale(float sx, float sy) sx,sy分别为图片在x,y轴方向上的缩放比例
- setScale(float sx, float sy, float px, float py) px,py为缩放的中心点坐标,即缩放过程中保持不变的点
- setTranslate(float dx, float dy) dx,dy分别为图片在x,y轴方向上的偏移量,注意平移无中心点
- setSkew(float kx, float ky) kx,ky为图片相对于x,y轴的倾斜量
- setSkew(float kx, float ky, float px, float py) px,py为图片倾斜的中心点坐标
注意:set是直接设置matrix的值,每次set一次,整个matrix的值都会变掉。所以如果进行组合变换的话,只能在第一次使用set,以后要使用post和pre,也可以只是用post。
以preRotate()为例:
可以看到pre操作是拿参数给出的矩阵右乘当前矩阵M,即pre执行的是一个右乘的操作。而在图形操作中,越靠近右边的矩阵就越先执行。所以,pre操作是在当前矩阵的最前面执行的。
post是拿参数给出的矩阵左乘当前矩阵M,即post执行的是一个左乘的操作。所以,post操作是在当前矩阵的最后面执行的。所以完全可以只使用post操作来完成所需的变换。
相关api请参看官方文档,这里不再一一解释。
本文代码下载:
http://download.csdn.net/detail/u012483425/9001425
参考博客:
http://blog.csdn.net/zzhou910/article/details/26379795
http://blog.csdn.net/loongggdroid/article/details/18706999
版权声明:本文为博主原创文章,未经博主允许不得转载。
原文地址:http://blog.csdn.net/u012483425/article/details/47609655