关于Canvas的小笔记

前言

这几天一直在看关于view的自定义方面的只是,在onDraw绘制时会经常用到画布Canvas,接下来对画布的知识做一些小总结。

一、剪裁方法clipRect(…)(类似于截屏)

此方法主要是在画布上街区一定区域的面积进行操作。

Rect

讲到截取一定区域的面积就要讲到Rect

canvas.drawRect(new Rect(150, 75, 260, 120), mPaint);

我们经常会看到这样一段代码,就是在画布上添加一个矩阵,而在drawRect中设置的Rect参数分别是矩阵的四个参数,由于是矩阵只需要确定左上角的坐标和右下角的坐标即可。上面代码中四个参数left,top,right,bottom,其实可以理解为(left,top)为左上角的坐标,(right,bottom)为右下角的坐标。

RectF

我们还会见到如RectF这个类,作用其实是和Rect一样的,只不过坐标的参数都会以folat类型来设置

**ps: 我们应该怎么把它放到屏幕的右下角,就是和屏幕的右侧和下侧都挨上 坐标是多少?我的屏幕是 320*480 按道理这个矩形的坐标应该是(210,435,320,480) 这其实 应该是正确的结果 ,但是如果把坐标改成这个 你运行一下 其实 这个矩形就消失在了屏幕上。 刚开始我困惑至极 也不知道怎么回事,后来发现 我们屏幕的 状态栏 和 标题栏

一共占了 50 正确的坐标应该是 (210,385,320,430);
这个时候它就在屏幕的右下角。 这里还是有疑问,就算 状态栏 和 标题栏 占去了 50 但是矩形最下面那条线 的位置应该还是480啊 ! 这是没错的啊 怎么会变成430 了 很好 我也不知道是怎么回事 我怀疑 是坐标原点 下移 坐标原点 在 状态栏和标题栏的底线。 http://blog.csdn.net/pilou5400/archive/2010/11/18/6018422.aspx 大家 可以去看看。**

二、intersect与union

这两个方法比较简单,主要是对画布中两个固定界面进行截取,intersect是取两个矩阵的交集,union是取两个矩阵的全集

 @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawColor(Color.BLUE);  

        Rect rect = new Rect(0, 0, 500, 500);  

        rect.intersect(250, 250, 750, 750); 

        canvas.clipRect(rect);
        canvas.drawColor(Color.RED);  
    }  
 protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawColor(Color.BLUE);  

        Rect rect = new Rect(0, 0, 500, 500);  

        rect.union(250, 250, 750, 750);  

        canvas.clipRect(rect);
        canvas.drawColor(Color.RED);  
    } 

具体使用方法如上。
关于剪裁的还有很多方法这里不一一介绍,这里主要是想记住大概canvas的一些用法和整体作用。

三、saveXXX和restoreXXX 画布层的概念

这里主要是讲层的概念。画布在使用的过程中参数是一致不断在变化的,当我们向画布中不断添加元素的过程中有时候还是希望位置大小等参数可以回滚。save方法就可以使我们之前的操作状态得以保存,restore则是使画布回到那个状态。

我们在save()后添加了旋转,绘制后释放了画布。你会发现旋转的只有蓝色的矩形,之后绘制的绿色圆形没有旋转。这就说明蓝色的矩形被我们放在了一个新的层上,在那里进行的操作是不会影响到之后的图层的。一旦你释放了画布,之后的操作就在别的层上了,所以我们的绿色圆形没有发生任何变化。

至此结合上一节对Canvas的一些原理阐述我们该对它有个全新的认识,之前我们一直称其为画布,其实更准确地说Canvas是一个容器,如果把Canvas理解成画板,那么我们的“层”就像张张夹在画板上的透明的纸,而这些纸对应到Android则是一个个封装在Canvas中的Bitmap。

@Override
    protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);

        mPaint.setColor(Color.RED);
        canvas.drawRect(50, 50, 250, 250, mPaint);


        // 保存画布
        canvas.save();
        // 旋转画布
        canvas.rotate(30); 

        mPaint.setColor(Color.BLUE);
        canvas.drawRect(100, 100, 200, 200, mPaint);

        // 还原画布
        canvas.restore();

        mPaint.setColor(Color.GREEN);
        canvas.drawCircle(150, 150, 40, mPaint);
    }

四、变换

说起变换,无非就几种:平移、旋转、缩放和错切,而我们的Canvas也继承了变换的精髓,同样提供了这几种相应的方法,像translate(float dx, float dy)方法平移画布用了无数次,这里再次强调,translate方法会改变画布的原点坐标,原点坐标对变换的影响弥足轻重!
scale(float sx, float sy)是对画布进行缩放
rotate(float degrees)和rotate(float degrees, float px, float py)
rotate(float degrees)和重载方法rotate(float degrees, float px, float py)它们的作用是旋转画布。这个在上面已经多次用到了,就不再赘述了。
skew(float sx, float sy)
kew(float sx, float sy)是错切方法,两个参数与scale类似表示横纵向的错切比率。所谓错切就是把图片分割为不同的格子,类似于棋盘。然后移动上面的各个交点的位置,让图片进行变换的效果。

这里介绍Matrix

Matrix是一个3*3的矩阵,其值对应如下:
下面给出具体坐标对应变形的属性
|scaleX, skewX, translateX|
|skewY, scaleY, translateY|
|0 ,0 , scale |
Matrix提供了一些方法来控制图片变换:
setTranslate(float dx,float dy):控制Matrix进行位移。
setSkew(float kx,float ky):控制Matrix进行倾斜,kx、ky为X、Y方向上的比例。
setSkew(float kx,float ky,float px,float py):控制Matrix以px、py为轴心进行倾斜,kx、ky为X、Y方向上的倾斜比例。
setRotate(float degrees):控制Matrix进行depress角度的旋转,轴心为(0,0)。
setRotate(float degrees,float px,float py):控制Matrix进行depress角度的旋转,轴心为(px,py)。
setScale(float sx,float sy):设置Matrix进行缩放,sx、sy为X、Y方向上的缩放比例。
setScale(float sx,float sy,float px,float py):设置Matrix以(px,py)为轴心进行缩放,sx、sy为X、Y方向上的缩放比例。
注意:以上的set方法,均有对应的post和pre方法,Matrix调用一系列set,pre,post方法时,可视为将这些方法插入到一个队列.当然,按照队列中从头至尾的顺序调用执行.其中pre表示在队头插入一个方法,post表示在队尾插入一个方法.而set表示把当前队列清空,并且总是位于队列的最中间位置.当执行了一次set后:pre方法总是插入到set前部的队列的最前面,post方法总是插入到set后部的队列的最后面
Demo

本文大部分内容参考自:

http://blog.csdn.net/aigestudio/article/details/41960507

http://blog.csdn.net/aigestudio/article/details/42677973

http://blog.csdn.net/airk000/article/details/38925059

我记录在此,作为学习笔记。

http://www.cnblogs.com/tianzhijiexian/p/4300988.html尊重原作者,感谢作者的无私分享

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值