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的原理、代码验证和应用

  • 相关阅读:
    repeater 设置分页
    table表格合并
    repeater分页
    http错误500.19 错误代码 0x80070021
    asp文件上传和下载
    asp:Repeater控件使用
    vs2013标签
    "Uncaught SyntaxError: Unexpected token <"错误完美解决
    监控系统说明文档
    限制input输入类型(多种方法实现)
  • 原文地址:https://www.cnblogs.com/wangjiaghe/p/7064476.html
Copyright © 2011-2022 走看看