Android Matrix对图像简单介绍

本篇文章是对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() 执行顺序是先到先执行。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值