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);//旋转后在平移回来