本篇文章是对Android Matrix API的简单介绍,需要的朋友参考下
Matrix的对图像的处理可分为四类基本变换:
Translate 平移变换
Rotate 旋转变换
Scale 缩放变换
Skew 错切变换
1. 平移变换
postTranslate(float dx, float dy)方法。
参数 dx: 移动x轴上的距离
参数 dy:移动y轴上的距离
使用方法
Matrix matrix = new Matrix();
// 1. 平移 在x方向平移 在y轴方向 ;
matrix.postTranslate(100, 100);
view.setImageMatrix(matrix);
补充: preTranslate(float dx, float dy)
preTranslate是指在setRotate前,平移,postTranslate是指在setRotate后平移
举例:以中心旋转放。由于旋转是以(0,0)为中心的,所以为了把界面的中心与(0,0)对齐,就要preTranslate(-centerX, -centerY),
setScale完成后,调用postTranslate(centerX, centerY),再把图片移回来,这样看到的动画效果就是activity的界面图片从中心不停的旋转了
setRotate(100);
preTranslate(-centerX, -centerY);
postTranslate(centerX, centerY);
等同于
setRotate(100,centerX, centerY);
2.旋转变换
setRotate(float degrees, float px, float py) 方法
参数degrees : 旋转角度
参数 px: 旋转中心点坐标x
参数 py: 旋转中心点坐标y
Matrix matrix = new Matrix();
matrix.setRotate(45f, 100f, 100f);
view.setImageMatrix(matrix);
3. 缩放变换
Matrix中与缩放操作相关的方法一共有6个,
public boolean postScale (float sx, float sy)
public boolean postScale (float sx, float sy, float px, float py)
public boolean preScale (float sx, float sy)
public boolean preScale (float sx, float sy, float px, float py)
public void setScale (float sx, float sy)
public void setScale (float sx, float sy, float px, float py)
其中参数sx,sy分别表示x轴和y轴的拉伸变化,如果大于1,为放大,小于1为缩小,为负值则表示对称的变化(在之后的组合变化中我们会用到它来实现镜子和倒影的效果);
setScale (float sx, float sy)默认为以(0,0)为指定缩放中心,即左上角。
setScale (float sx, float sy, float px, float py) 参数px,py用于指定缩放的中心(就是当缩放变化后该点的位置坐标不会变)。这个地方可能有些同学不知道什么意思,就这个方法做个详细的介绍:
比如代码
Matrix matrix = new Matrix();
matrix.setScale(2f, 2f,100,100);
view.setImageMatrix(matrix);
view放大两倍。等同于
Matrix matrix = new Matrix();
matrix.setScale(2f, 2f);
matrix.postTranslate(100,100);
view.setImageMatrix(matrix);
setScale()是对整个坐标系缩放,也就是point(px,py)也要缩放,但是point(px,py)又不能变,所以缩放后,有做对应的移动。
4. 倾斜操作
Matrix中关于倾斜操作的方法有6个
public boolean postSkew (float kx, float ky)
public boolean postSkew (float kx, float ky, float px, float py)
public boolean preSkew (float kx, float ky)
public boolean preSkew (float kx, float ky, float px, float py)
public void setSkew (float kx, float ky)
public void setSkew (float kx, float ky, float px, float py)
点(x,y)经过skew(kx,ky,px,py)变换之后,坐标为(kx*(y-py)+px,ky*(x-px)+py),如果,px和py没有,则默认为都为0。
错切 - 水平
matrix.setSkew(2f, 0f);
错切 - 垂直
matrix.setSkew(0f, 1f);
直接上代码:
public class TestTransformMatrixActivity extends Activity
implements View.OnTouchListener {
private TransformMatrixView view;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_test);
view = (TransformMatrixView) findViewById(R.id.img_fresh);
view.setScaleType(ImageView.ScaleType.MATRIX);
view.setOnTouchListener(this);
}
public boolean onTouch(View v, MotionEvent e) {
if (e.getAction() == MotionEvent.ACTION_UP) {
Matrix matrix = new Matrix();
// 输出图像的宽度和高度(162 x 251)
Log.e("ttt", "image size: width x height = " + view.getImageBitmap().getWidth() + " x " + view.getImageBitmap().getHeight());
// 1. 平移 在x方向平移view.getImageBitmap().getWidth(),在y轴方向view.getImageBitmap().getHeight()
// matrix.postTranslate(view.getImageBitmap().getWidth(), view.getImageBitmap().getHeight());
// 2. 旋转(围绕图像的中心点)
// matrix.setRotate(45f, view.getImageBitmap().getWidth() / 2f, view.getImageBitmap().getHeight() / 2f);
// matrix.setRotate(180f, 300f, 600f);
// // 3. 旋转(围绕坐标原点) + 平移(效果同2)
// matrix.setRotate(45f);
// matrix.preTranslate(-1f * view.getImageBitmap().getWidth() / 2f, -1f * view.getImageBitmap().getHeight() / 2f);
// matrix.postTranslate((float)view.getImageBitmap().getWidth() / 2f, (float)view.getImageBitmap().getHeight() / 2f);
// 4. 缩放
// matrix.setScale(3f, 2f,100,100);
// matrix.postTranslate(200,100);
// // 5. 错切 - 水平
// matrix.setSkew(2f, 0f);
// // 6. 错切 - 垂直
// matrix.setSkew(0f, 0.5f,300,600);
//
// 7. 错切 - 水平 + 垂直
// matrix.setSkew(0.5f, 0.5f);
// 8. 对称 (水平对称)
// float matrix_values[] = {1f, 0f, 0f, 0f, -1f, 0f, 0f, 0f, 1f};
// matrix.setValues(matrix_values);
// // 9. 对称 - 垂直
// float matrix_values[] = {-1f, 0f, 500f, 0f, 1f, 0f, 0f, 0f, 1f};
// matrix.setValues(matrix_values);
// 做下面的平移变换,纯粹是为了让变换后的图像和原图像不重叠
// matrix.postTranslate(view.getImageBitmap().getWidth() , 0f);
// // 10. 对称(对称轴为直线y = x)
float matrix_values[] = {0f, -1f, 0f, -1f, 0f, 0f, 0f, 0f, 1f};
matrix.setValues(matrix_values);
// 做下面的平移变换,纯粹是为了让变换后的图像和原图像不重叠
// matrix.postTranslate(view.getImageBitmap().getHeight() + view.getImageBitmap().getWidth(),
// view.getImageBitmap().getHeight() + view.getImageBitmap().getWidth());
view.setImageMatrix(matrix);
// 下面的代码是为了查看matrix中的元素
float[] matrixValues = new float[9];
matrix.getValues(matrixValues);
for (int i = 0; i < 3; ++i) {
StringBuilder temp = new StringBuilder();
for (int j = 0; j < 3; ++j) {
temp.append(matrixValues[3 * i + j]).append("\t");
}
Log.e("Tt", temp.toString());
}
view.invalidate();
}
return true;
}
}
TransformMatrixView.java
public class TransformMatrixView extends ImageView {
Paint paint;
private Bitmap bitmap;
private Matrix matrix;
public TransformMatrixView(Context context) {
this(context, null, 0);
}
public TransformMatrixView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public TransformMatrixView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.pan);
matrix = new Matrix();
paint = new Paint();
paint.setColor(Color.BLUE);
paint.setStrokeWidth(5);
}
@Override
protected void onDraw(Canvas canvas) {
// 画出原图像
canvas.drawBitmap(bitmap, 0, 0, null);
// 画出变换后的图像
canvas.drawBitmap(bitmap, matrix, null);
canvas.drawPoint(300, 600, paint);
super.onDraw(canvas);
}
@Override
public void setImageMatrix(Matrix matrix) {
this.matrix.set(matrix);
super.setImageMatrix(matrix);
}
public Bitmap getImageBitmap() {
return bitmap;
}
}
提示: preMethod() 执行顺序是先到后执行(栈)。 postMethod() 执行顺序是先到先执行。