美文网首页程序员Android知识Android开发经验谈
Android Canvas方法总结最全面详解API(三)

Android Canvas方法总结最全面详解API(三)

作者: 侯蛋蛋_ | 来源:发表于2017-10-30 13:44 被阅读0次

    本节引言:

    在Canvas的API文档中,我们看到这样一个方法:drawBitmap(Bitmap bitmap, Matrix matrix, Paint paint)
    这个Matrix可是有大文章的,前面我们在学Paint的API中的ColorFilter中曾讲过ColorMatrix 颜色矩阵,一个4 * 5 的矩阵,我们可以通过修改矩阵值来修改色调,饱和度等! 而今天讲的这个Matrix可以结合其他API来控制图形,组件的变换。比如Canvas就提供了上面的 这个drawBitmap来实现矩阵变换的效果!下面我们来慢慢研究这个东东~

    1.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轴上的缩放比例

    其实和Canvas变换的方法基本一致,在为Matrix设置了上面的变换后,调用Canvas的 drawBitmap()方法调用矩阵就好~

    2.Matrix使用示例:

    运行效果图

    代码实现

    MyView.java:

    public class MyView 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 MyView(Context context) {
            this(context, null);
        }
    
        public MyView(Context context, AttributeSet attrs) {
            super(context, attrs);
            init();
        }
    
        public MyView(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
        }
    
        private void init() {
            mBitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.img_meizi);
            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();
        }
    }
    

    MainActivity.java:

    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 MyView myView;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            bindViews();
        }
    
        private void bindViews() {
            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);
            myView = (MyView) findViewById(R.id.myView);
    
    
            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:
                    myView.setMethod(0);
                    break;
                case R.id.btn_left:
                    myView.setMethod(1);
                    break;
                case R.id.btn_right:
                    myView.setMethod(2);
                    break;
                case R.id.btn_zoomin:
                    myView.setMethod(3);
                    break;
                case R.id.btn_zoomout:
                    myView.setMethod(4);
                    break;
            }
        }
    }
    

    布局就不写了,很简单

    3.drawBitmapMash扭曲图像

    在API文档中还有这样一个方法: drawBitmapMesh(Bitmap bitmap, int meshWidth, int meshHeight, float[] verts, int vertOffset, int[] colors, int colorOffset, Paint paint)
    参数依次是:

    • bitmap:需要扭曲的原位图
    • meshWidth/meshHeight:在横/纵向上把原位图划分为多少格
    • verts:长度为(meshWidth+1)*(meshHeight+2)的数组,他记录了扭曲后的位图各顶点(网格线交点) 位置,虽然他是一个一维数组,但是实际上它记录的数据是形如(x0,y0),(x1,y1)..(xN,Yn)格式的数据, 这些数组元素控制对bitmap位图的扭曲效果
    • vertOffset:控制verts数组从第几个数组元素开始对bitmap进行扭曲(忽略verOffset之前数据 的扭曲效果)

    代码示例
    运行效果图

    相关文章

      网友评论

        本文标题:Android Canvas方法总结最全面详解API(三)

        本文链接:https://www.haomeiwen.com/subject/cqrppxtx.html