zoukankan      html  css  js  c++  java
  • 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的原理、代码验证和应用

  • 相关阅读:
    SpringBoot实现原理
    常见Http状态码大全
    forward(转发)和redirect(重定向)有什么区别
    1094. Car Pooling (M)
    0980. Unique Paths III (H)
    1291. Sequential Digits (M)
    0121. Best Time to Buy and Sell Stock (E)
    1041. Robot Bounded In Circle (M)
    0421. Maximum XOR of Two Numbers in an Array (M)
    0216. Combination Sum III (M)
  • 原文地址:https://www.cnblogs.com/wangjiaghe/p/7064476.html
Copyright © 2011-2022 走看看