• Android中强大的Matrix及图像变换操作


    一: 简介

    Matrix翻译字面意思时矩阵,在Android的API中提供了两种Matrix,分别是android.graphics.Matrix 和 android.opengl.Matrix .

    后者是OpenGL中的 , 是 一个四行四列的 矩阵. 主要是3D 效果,导包的时候,注意

    前者是我们比较常用的, 是一个三行三列的矩阵 , 主要是2D方面的.主要主要用于图像的处理,主要功能有 缩放[Scale] ,平移[Translate] ,旋转[Rotate],倾斜[Skew]等操作.

    其中 rotate 操作涉及到的参数是:MSCALE_X,MSKEW_X,MSKEW_Y,MSCALE_Y

    translate操作涉及到的参数是:MTRANS_X,MTRANS_Y

    scale操作涉及到的参数是:MSCALE_X,MSCALE_Y

    skew操作涉及到的参数是:MSKEW_X,MSKEW_Y

    更多的相关操作详见 http://blog.csdn.net/forlong401/article/details/8174452

    二:注意事项

    图像的处理, Translate用到了矩阵的加法,其他操作则用到的是矩阵的乘法 :

    77c093fd-764d-376e-abf6-08400901c306 (1)

    sinX 和 cosX :表示旋转角度的 cos 值和 sin 值(逆时针为正) ;

    translateX 和 translateY: 表示 x 和 y 的平移量 ;

    scale 是缩放的比例, 1 是不变, 2 是表示缩放 1/2。

    除平移变换(Translate)外,旋转变换(Rotate)、缩放变换(Scale)和错切变换(Skew)都可以围绕一个中心点来进行,如果不指定,在默认情况下是围绕(0, 0)来进行相应的变换的。

    三: 简单使用

    自定义View:

    package com.example.matrixdemo;
    
    import android.content.Context;
    import android.graphics.Bitmap;
    import android.graphics.Canvas;
    import android.graphics.Matrix;
    import android.graphics.drawable.BitmapDrawable;
    import android.util.AttributeSet;
    import android.view.View;
    
    public class MyView extends View {
    
        private Bitmap mBitmap;
    
        private Matrix mMatrix = new Matrix();
    
        public MyView(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
            initialize();
        }
    
        public MyView(Context context, AttributeSet attrs) {
            this(context, attrs, 0);
        }
    
        public MyView(Context context) {
    
            this(context, null);
        }
    
        private void initialize() {
    
            mBitmap = ((BitmapDrawable) getResources().getDrawable(R.drawable.mm))
                    .getBitmap();
    
            float cosValue = (float) Math.cos(-Math.PI / 6);
    
            float sinValue = (float) Math.sin(-Math.PI / 6);
    
            mMatrix.setValues(
        //缩放1/2 ,平移(100,100),旋转30°
            new float[] {
    
            cosValue, -sinValue, 100,
    
            sinValue, cosValue, 100,
    
            0, 0, 2 });
    
        }
    
        @Override
        protected void onDraw(Canvas canvas) {
    
            super.onDraw(canvas);
    
            canvas.drawBitmap(mBitmap, mMatrix, null);
    
        }
    
    }

    XML:

    <?xml version="1.0" encoding="utf-8"?>
    <com.example.matrixdemo.MyView xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >
    
    </com.example.matrixdemo.MyView>

    Activity:

    package com.example.matrixdemo;
    
    import android.app.Activity;
    import android.os.Bundle;
    
    public class MatrixRotate extends Activity {
        
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.my_view);
        }
    }

    运行效果:

    捕获

    注意: 因为缩小了一半,所以平移了50

    四:相关API

    如果只是这样设置值的话.还要计算好半天,很麻烦,google为我们提供了响应的API.针对每种变换,Android提供了pre、set和post三种操作方式

    set用于设置Matrix中的值。

    pre方法表示矩阵前乘,例如:变换矩阵为A,原始矩阵为B,pre方法的含义即是A*B

    post方法表示矩阵后乘,例如:变换矩阵为A,原始矩阵为B,post方法的含义即是B*A

    简单理解:

    matrix.preScale(0.5f, 1);   
    matrix.preTranslate(10, 0);  
    matrix.postScale(0.7f, 1);    
    matrix.postTranslate(15, 0);

    等价于:

    translate(10, 0) -> scale(0.5f, 1) -> scale(0.7f, 1) -> translate(15, 0)

    调用的pre的操作先执行,调用的post的操作则后执行。

    set方法是调用即

    覆盖之前matrix中的所有变换,

    matrix.preScale(0.5f, 1);   
    matrix.setScale(1, 0.6f);   
    matrix.postScale(0.7f, 1);   
    matrix.preTranslate(15, 0);

    等价于

    translate(15, 0) -> scale(1, 0.6f) ->  scale(0.7f, 1)

    matrix.preScale (0.5f, 1)将不起作用。

    同样满足pre后调用先执行原则,只是set之前的值无效.

     五: API使用实例

      比如我们要将一个图片旋转60°,之后平移(100,100)

    //
    Matrix m = new Matrix();
    m.postRotate(60); m.postTranslate(100, 100); //或者: Matrix m = new Matrix(); m.setTranslate(100 , 100 ); m.preRotate(60);

    自定义View

    package com.example.matrixdemo;
    
    import android.content.Context;
    import android.graphics.Bitmap;
    import android.graphics.Canvas;
    import android.graphics.Matrix;
    import android.graphics.drawable.BitmapDrawable;
    import android.util.AttributeSet;
    import android.view.View;
    
    public class MyView extends View {
    
        private Bitmap mBitmap;
        private Matrix mMatrix = new Matrix();
    
        public MyView(Context context) {
            this(context, null);
        }
    
        public MyView(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
            initialize();
        }
    
        public MyView(Context context, AttributeSet attrs) {
            this(context, attrs, 0);
        }
    
        private void initialize() {
    
            Bitmap bmp = ((BitmapDrawable) getResources()
                    .getDrawable(R.drawable.mm)).getBitmap();
            mBitmap = bmp;
            /*
             * 缩放到100*100;这里需要注意前面是float值
             */
            mMatrix.setScale(100f / bmp.getWidth(), 100f / bmp.getHeight());
            // 平移到(100,100)
            mMatrix.postTranslate(100, 100);
            // 以(100,100)为中心,倾斜x和y轴
            mMatrix.postSkew(0.2f, 0.2f, 100, 100);
        }
    
        @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
    
            canvas.drawBitmap(mBitmap, mMatrix, null);
        }
    }

    运行效果:

    捕获

  • 相关阅读:
    mysql innodb ini
    innodb_flush_method
    mysql查询缓存
    查看表的索引
    mysql key PRI UNI MUL
    E160028
    mysql命令
    No identifier specified for entity
    在画图板中添加文本并更改文本颜色
    在Windows资源管理器中预览PowerShell文件
  • 原文地址:https://www.cnblogs.com/BoBoMEe/p/4299842.html
Copyright © 2020-2023  润新知