Android绘图之Matrix

一、概述

 1. 在Android中,如果你用Matrix进行过图像处理,那么一定知道Matrix这个类。Android中的Matrix是一个3 x 3的矩阵,其内容如下

  

2.Matrix的对图像的处理可分为四类基本变换:

  Translate           平移变换

  Rotate                旋转变换

  Scale                  缩放变换

  Skew                  错切变换

针对每种变换,Android提供了pre、set和post三种操作方式。其中
set用于设置Matrix中的值。
pre是先乘,因为矩阵的乘法不满足交换律,因此先乘、后乘必须要严格区分。先乘相当于矩阵运算中的右乘。
post是后乘,因为矩阵的乘法不满足交换律,因此先乘、后乘必须要严格区分。后乘相当于矩阵运算中的左乘。

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

  

二、常用操作

1.平移  

matrix.postTranslate(view.getImageBitmap().getWidth(), view.getImageBitmap().getHeight());

2.缩放

matrix.setScale(2f, 2f);

 

3.旋转

//第一种方式
        //旋转 围绕图片中心
        matrix.setRotate(45f,view.getImageBitmap().getWidth()/2f,view.getImageBitmap().getHeight()/2f);
        //平移
        matrix.postTranslate(view.getImageBitmap().getWidth()*1.5f,0f);



        //第二种方式
        //旋转  中心点(0,0)
        matrix.setRotate(45f);

        //先将图片中心移到(0,0),旋转后再移到原位置
        matrix.preTranslate(-view.getImageBitmap().getWidth()/2f,-view.getImageBitmap().getHeight()/2f);
        matrix.postTranslate(view.getImageBitmap().getWidth()*2f,view.getImageBitmap().getHeight()/2f);

 

4.错切

     matrix.setSkew(0.5f,0f);//水平
        matrix.setSkew(0f,0.5f);//竖直
        matrix.setSkew(0.5f,0.5f);//水平和数值

 

5.对称

 1)x轴对称

float matrix_values[] = {1f, 0f, 0f, 0f, -1f, 0f, 0f, 0f, 1f};
matrix.setValues(matrix_values);

 2)Y轴对称

float matrix_values[] = {-1f, 0f, 0f, 0f, 1f, 0f, 0f, 0f, 1f};
matrix.setValues(matrix_values);

 3)y=x对称

float matrix_values[] = {0f, -1f, 0f, -1f, 0f, 0f, 0f, 0f, 1f};
matrix.setValues(matrix_values);

 

三、代码

1.xml文件

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/rl"
        >
        <com.example.dhj.bitmapdemo.TransformMatrixView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:id="@+id/view"
            />
    </RelativeLayout>

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:visibility="visible"

        >

        <Button
            android:id="@+id/button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:layout_alignParentLeft="true"
            android:layout_alignParentStart="true"
            android:layout_marginBottom="135dp"
            android:onClick="click"
            android:text="平移" />

        <Button
            android:id="@+id/button2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignBaseline="@+id/button"
            android:layout_alignBottom="@+id/button"
            android:layout_marginLeft="17dp"
            android:layout_marginStart="17dp"
            android:layout_toEndOf="@+id/button"
            android:layout_toRightOf="@+id/button"
            android:onClick="click"
            android:text="旋转" />

        <Button
            android:id="@+id/button3"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignBottom="@+id/button2"
            android:layout_marginLeft="35dp"
            android:layout_marginStart="35dp"
            android:layout_toEndOf="@+id/button2"
            android:layout_toRightOf="@+id/button2"
            android:onClick="click"
            android:text="水平倾斜" />

        <Button
            android:id="@+id/button4"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignBaseline="@+id/button5"
            android:layout_alignBottom="@+id/button5"
            android:layout_alignParentLeft="true"
            android:layout_alignParentStart="true"
            android:onClick="click"
            android:text="竖直倾斜" />

        <Button
            android:id="@+id/button5"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignLeft="@+id/button2"
            android:layout_alignStart="@+id/button2"
            android:layout_below="@+id/button2"
            android:onClick="click"
            android:text="水平竖直倾斜" />

        <Button
            android:id="@+id/button6"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignLeft="@+id/button3"
            android:layout_alignStart="@+id/button3"
            android:layout_below="@+id/button3"
            android:onClick="click"
            android:text="x轴对称" />

        <Button
            android:id="@+id/button7"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_alignParentStart="true"
            android:layout_below="@+id/button4"
            android:layout_marginTop="15dp"
            android:onClick="click"
            android:text="y轴对称" />

        <Button
            android:id="@+id/button8"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignBottom="@+id/button7"
            android:layout_alignLeft="@+id/button5"
            android:layout_alignStart="@+id/button5"
            android:onClick="click"
            android:text="y=x对称" />

        <Button
            android:id="@+id/button11"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignLeft="@+id/button6"
            android:layout_alignStart="@+id/button6"
            android:layout_alignTop="@+id/button8"
            android:onClick="click"
            android:text="缩放" />


    </RelativeLayout>


</FrameLayout>

  

2.自定义view

class TransformMatrixView extends ImageView
    {
        private Bitmap bitmap;
        private Matrix matrix;
        public TransformMatrixView(Context context)
        {
            super(context);
            Bitmap b = BitmapFactory.decodeResource(getResources(), R.drawable.p1);
            bitmap=resizeBitmap(b,162,251);
            matrix = new Matrix();
            setBackgroundColor(Color.parseColor("#3f51b5"));
        }

        public TransformMatrixView(Context context, @Nullable AttributeSet attrs) {
            super(context, attrs);
            Bitmap b = BitmapFactory.decodeResource(getResources(), R.drawable.p1);
            bitmap=resizeBitmap(b,162,251);
            matrix = new Matrix();
//            setBackgroundColor(Color.parseColor("#3f51b5"));
        }

        @Override
        protected void onDraw(Canvas canvas)
        {
            // 画出原图像  
            canvas.drawBitmap(bitmap, 0, 0, null);
            // 画出变换后的图像  
            canvas.drawBitmap(bitmap, matrix, null);
            super.onDraw(canvas);
        }

        @Override
        public void setImageMatrix(Matrix matrix)
        {
            this.matrix.set(matrix);
            super.setImageMatrix(matrix);
        }

        public Bitmap getImageBitmap()
        {
            return bitmap;
        }


        /**
         * 使用Matrix将Bitmap压缩到指定大小
         * @param bitmap
         * @param w
         * @param h
         * @return
         */
        public static Bitmap resizeBitmap(Bitmap bitmap, int w, int h)
        {
            int width = bitmap.getWidth();
            int height = bitmap.getHeight();

            float scaleWidth = ((float) w) / width;
            float scaleHeight = ((float) h) / height;

            Matrix matrix = new Matrix();
            matrix.postScale(scaleWidth, scaleHeight);

            Bitmap resizedBitmap = Bitmap.createBitmap(bitmap, 0, 0, width,
                    height, matrix, true);
            return resizedBitmap;
        }
    }

 

3.activity

public class MainActivity extends Activity {
    private TransformMatrixView view;
    Matrix matrix= new Matrix();
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.activity_main);
        view= (TransformMatrixView) findViewById(R.id.view);

    }



    public void click(View v){
        switch (v.getId()){
            case R.id.button:
                tranlate();
                break;
            case R.id.button2:
                rorate();
                break;
            case R.id.button3:
                skewhorizontal();
                break;
            case R.id.button4:
                skewVertical();
                break;
            case R.id.button5:
                skew();
                break;
            case R.id.button6:
                symmetryHorizontal();
                break;
            case R.id.button7:
                symmetryVertical();
                break;
            case R.id.button8:
                symmetry();
                break;
            case R.id.button11:
                scale();
                break;


        }
        view.setImageMatrix(matrix);
//        view.invalidate();
    }

    //平移
    private void tranlate(){
        // 输出图像的宽度和高度(162 x 251)
//            Log.e("TestTransformMatrixActivity", "image size: width x height = " +  view.getImageBitmap().getWidth() + " x " + view.getImageBitmap().getHeight());
        // 1. 平移
        matrix.postTranslate(view.getImageBitmap().getWidth(), view.getImageBitmap().getHeight());
        // 在x方向平移view.getImageBitmap().getWidth(),在y轴方向view.getImageBitmap().getHeight()


    }

    //旋转
    private void rorate(){
        //第一种方式
        //旋转 围绕图片中心
        matrix.setRotate(45f,view.getImageBitmap().getWidth()/2f,view.getImageBitmap().getHeight()/2f);
        //平移
        matrix.postTranslate(view.getImageBitmap().getWidth()*1.5f,0f);



        //第二种方式
        //旋转  中心点(0,0)
        matrix.setRotate(45f);

        //先将图片中心移到(0,0),旋转后再移到原位置
        matrix.preTranslate(-view.getImageBitmap().getWidth()/2f,-view.getImageBitmap().getHeight()/2f);
        matrix.postTranslate(view.getImageBitmap().getWidth()*2f,view.getImageBitmap().getHeight()/2f);

    }

    //缩放
    private void scale(){
        matrix.setScale(2f, 2f);
        matrix.postTranslate(view.getImageBitmap().getWidth(),view.getImageBitmap().getHeight());

    }

    //水平 倾斜
    private void skewhorizontal(){
//        matrix.setSkew(0.5f, 0f);
//        matrix.postTranslate(view.getImageBitmap().getWidth(), 0f);
        matrix.setSkew(0.5f,0f);
        matrix.postTranslate(view.getImageBitmap().getWidth(),0f);

    }

    //竖直  倾斜
    private void skewVertical(){
        matrix.setSkew(0f,0.5f);
        matrix.postTranslate(view.getImageBitmap().getWidth(),0f);

    }

    //倾斜 水平和竖直
    private void skew(){
        matrix.setSkew(0.5f,0.5f);
        matrix.postTranslate(view.getImageBitmap().getWidth(),0f);
    }

    //x轴对称
    private void symmetryHorizontal(){
        float matrix_values[] = {1f, 0f, 0f, 0f, -1f, 0f, 0f, 0f, 1f};
        matrix.setValues(matrix_values);
        matrix.postTranslate(0f,view.getImageBitmap().getHeight()*2);
    }

    //y轴对称
    private void symmetryVertical(){
        float matrix_values[] = {-1f, 0f, 0f, 0f, 1f, 0f, 0f, 0f, 1f};
        matrix.setValues(matrix_values);
        matrix.postTranslate(view.getImageBitmap().getWidth()*2,0f);
    }


    //对称 y=x
    private void symmetry(){
        float matrix_values[] = {0f, -1f, 0f, -1f, 0f, 0f, 0f, 0f, 1f};
        matrix.setValues(matrix_values);
        matrix.postTranslate(view.getImageBitmap().getWidth()+view.getImageBitmap().getHeight(),
                view.getImageBitmap().getHeight()+view.getImageBitmap().getWidth());
    }
    
}

 

 

四、效果

  

 

参考:

Android中图像变换Matrix的原理、代码验证和应用

 

posted @ 2017-06-22 13:34  段合江  阅读(224)  评论(0编辑  收藏  举报