Android Matrix矩阵

2,659 阅读2分钟

Matrix

Matrix是一个矩阵,主要功能是坐标映射,数值转换,在View,图片,动画效果等各个方面均有运用。
基本变换有4种:

  • 平移(Translate)
  • 缩放(Scale)
  • 旋转(Rotate)
  • 错切(Skew)


原图

private Paint mPaint = new Paint();
private Matrix mMatrix = new Matrix();
private Bitmap mBitmap;

mPaint.setStyle(Paint.Style.STROKE);
mPaint.setColor(Color.BLACK);
mPaint.setStrokeWidth(4);

//缩小图片
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 2;
mBitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.buteys,options);canvas.translate(getWidth() / 2-mBitmap.getWidth()/2, getHeight() / 2-mBitmap.getHeight()/2);//平移画布
canvas.drawBitmap(mBitmap, mMatrix, mPaint);



设置 mMatrix.setScale(0.5f, 0.5f);//当值为 1 时 显示原图,0.5f,0.5f 时 缩小一半



mMatrix.setTranslate(100, 100);//x,y 轴 都平移一百 



mMatrix.setRotate(45);//旋转45度



mMatrix.setSkew(0f, 0f);// 错切
当 x,y都为0时,显示正常的图片



mMatrix.setSkew(0.5f, 0.0f);// 错切 x设置为 0.5f y不变


mMatrix.setSkew(0.0f, 0.5f);// 错切 y设置为 0.5f x不变



mMatrix.setSkew(0.5f, 0.5f);// x,y同时设置0.5f时



注意的时,当同时设置多个 set 属性,生效的只有最后一个属性设置

例如:以下三个设置 生效的只有  Matrix.setRotate(45);

mMatrix.setScale(0.5f, 0.5f);
mMatrix.setTranslate(100, 100);
Matrix.setRotate(45);

但是如果 我们想同时设置 这几个属性,怎么办了?

mMatrix.preScale(0.8f, 0.8f);
mMatrix.preTranslate(100,100);
mMatrix.postRotate(45);
mMatrix.postSkew(0.5f, 0f);

我们可以使用 pre 开头的方法来设置


关于 pre 和 post 的理解

pre是 发生在 matrix.set 属性之前调用 而post是发生在之后调用

例如 

centerX和centerY是界面中心的坐标,图片铺满全屏,和屏幕一样大

 matrix.setScale(interpolatedTime, interpolatedTime); 

 matrix.preTranslate(-centerX, -centerY); 

 matrix.postTranslate(centerX, centerY);

经常在中心缩放的应用中看到这段代码. 

 preTranslate是指在setScale前,平移,postTranslate是指在setScale后平移 

注意他们参数是平移的距离,而不是平移目的地的坐标! 

 由于 缩放 Matrix 是以(0,0)即手机左上角的坐标

 为中心的,所以为了把图片的中心与(0,0)对齐,

 就要preTranslate(-centerX, -centerY), 

 setScale完成后,调用postTranslate(centerX, centerY),再把图片移回来


使用camer实现3D效果

//平移画布 至屏幕中心点
canvas.translate(getWidth() / 2, getHeight() / 2);
Camera camera = new Camera();
camera.save();
camera.rotateY(45);
camera.getMatrix(mMatrix);
camera.restore();
//mMatrix.preTranslate(0, -mBitmap.getHeight() / 2);
//mMatrix.postTranslate(0, mBitmap.getHeight() / 2);
canvas.drawBitmap(mBitmap, mMatrix, mPaint);



平移画布后,可以看到此时的圆心坐标为屏幕中心,图片(黑框)的位置如图,执行以上代码

后可以看到旋转的图片上下并不对称,因为Camera的rotateY()方法在以y轴旋转的时候,旋转中心是(0,0),因为旋转中心并不在图片的对称点上,所以得到的结果就是图片上下不对称。



那么我们只要让旋转中心在对称点上就可以了,这就要说preTranslate()和postTranslate()方法了,这两个方法可以实现我们所谓的旋转中心的改变


mMatrix.preTranslate(0, -mBitmap.getHeight() / 2);//旋转前平移至对称点
mMatrix.postTranslate(0, mBitmap.getHeight() / 2);//旋转后在平移回来