Android Canvas 矩阵变换 Matrix

我们再来看看 Canvas 的方法 drawBitmap() ,这个方法的第二个参数可有意思了,可用于实现很多效果

drawBitmap(Bitmap bitmap, Matrix matrix, Paint paint) 

使用矩阵 Matrix 可以让图片实现很多效果,比如放大缩小,左倾斜有倾斜等

Matrix

Matrix 有很多方法,我们介绍其中的几个

方法 说明
setTranslate(float dx, float dy) 控制 Matrix 进行平移
setRotate(float degrees, float px, float py) 旋转,参数:旋转角度,轴心(x,y)
setScale(float sx, float sy, float px, float py) 缩放,参数:X,Y轴上的缩放比例,缩放的轴心
setSkew(float kx, float ky) 倾斜,参数:X,Y轴上的缩放比例

范例

我们就写一个 demo 来演示上面提到的四个方法,先来看看最后的效果图


  1. 创建一个 空的 Android 项目 cn.twle.android.BitmapMatrix

  2. 下载 /static/i/meimei_rect.jpg,并把所有的图片拖到 res/drawable 目录下

  3. 创建一个自定义 View 类 MsView.java

    package cn.twle.android.bitmapmatrix;
    
    import android.content.Context;
    import android.graphics.Bitmap;
    import android.graphics.BitmapFactory;
    import android.graphics.Canvas;
    import android.graphics.Matrix;
    import android.util.AttributeSet;
    import android.view.View;
    
    public class MsView extends View {
    
        private Bitmap mBitmap;
        private Matrix matrix = new Matrix();
        private float sx = 0.0f;          //设置倾斜度
        private int width,height;         //位图宽高
        private float scale = 1.0f;       //缩放比例
        private int method = 0;
    
        public MsView(Context context) {
            this(context, null);
        }
    
        public MsView(Context context, AttributeSet attrs) {
            super(context, attrs);
            init();
        }
    
        public MsView(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
        }
    
        private void init() {
            mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.meimei_rect);
            width = mBitmap.getWidth();
            height = mBitmap.getHeight();
        }
    
        @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
            switch (method){
                case 0:
                    matrix.reset();
                    break;
                case 1:
                    sx += 0.1;
                    matrix.setSkew(sx,0);
                    break;
                case 2:
                    sx -= 0.1;
                    matrix.setSkew(sx,0);
                    break;
                case 3:
                    if(scale < 2.0){
                        scale += 0.1;
                    }
                    matrix.setScale(scale,scale);
                    break;
                case 4:
                    if(scale > 0.5){
                        scale -= 0.1;
                    }
                    matrix.setScale(scale,scale);
                    break;
            }
            //根据原始位图与Matrix创建新图片
            Bitmap bitmap = Bitmap.createBitmap(mBitmap,0,0,width,height,matrix,true);
            canvas.drawBitmap(bitmap,matrix,null);    //绘制新位图
        }
    
        public void setMethod(int i){
            method = i;
            postInvalidate();
        }
    }
    
  4. 然后修改布局 activity_main.xml

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    
        <LinearLayout
            android:id="@+id/ms_bar"
            android:layout_width="match_parent"
            android:layout_height="64dp"
            android:layout_alignParentBottom="true">
    
            <Button
                android:id="@+id/btn_reset"
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:text="重置" />
    
            <Button
                android:id="@+id/btn_left"
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:text="左倾" />
    
            <Button
                android:id="@+id/btn_right"
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:text="右倾" />
    
            <Button
                android:id="@+id/btn_zoomin"
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:text="放大" />
    
            <Button
                android:id="@+id/btn_zoomout"
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:text="缩小" />
        </LinearLayout>
    
        <cn.twle.android.bitmapmatrix.MsView
            android:id="@+id/msView"
            android:layout_width="400dp"
            android:layout_height="400dp"
            android:layout_above="@id/ms_bar" />
    
    </RelativeLayout>
    
  5. 最后修改 MainActivity.java

    package cn.twle.android.bitmapmatrix;
    
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.view.View;
    import android.widget.Button;
    
    public class MainActivity extends AppCompatActivity implements View.OnClickListener{
    
        private Button btn_reset;
        private Button btn_left;
        private Button btn_right;
        private Button btn_zoomin;
        private Button btn_zoomout;
        private MsView msView;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            btn_reset = (Button) findViewById(R.id.btn_reset);
            btn_left = (Button) findViewById(R.id.btn_left);
            btn_right = (Button) findViewById(R.id.btn_right);
            btn_zoomin = (Button) findViewById(R.id.btn_zoomin);
            btn_zoomout = (Button) findViewById(R.id.btn_zoomout);
            msView = (MsView) findViewById(R.id.msView);
    
            btn_reset.setOnClickListener(this);
            btn_left.setOnClickListener(this);
            btn_right.setOnClickListener(this);
            btn_zoomin.setOnClickListener(this);
            btn_zoomout.setOnClickListener(this);
    
        }
    
        @Override
        public void onClick(View v) {
            switch (v.getId()){
                case R.id.btn_reset:
                    msView.setMethod(0);
                    break;
                case R.id.btn_left:
                    msView.setMethod(1);
                    break;
                case R.id.btn_right:
                    msView.setMethod(2);
                    break;
                case R.id.btn_zoomin:
                    msView.setMethod(3);
                    break;
                case R.id.btn_zoomout:
                    msView.setMethod(4);
                    break;
            }
        }
    }
    

参考文档

  1. 官方API文档: Matrix

Android 基础教程

关于   |   FAQ   |   我们的愿景   |   广告投放   |  博客

  简单教程,简单编程 - IT 入门首选站

Copyright © 2013-2022 简单教程 twle.cn All Rights Reserved.