canvas教程

自定义控件之绘图篇:Canvas与图层(一)(2)

字号+ 作者:H5之家 来源:H5之家 2017-08-27 18:01 我要评论( )

savelayer新建的画布上的图像做为目标图像,矩形所在的透明图层与之相交,计算结果画在新建的透明画布上。最终将计算结果直接盖在原始画布上,形成最终的显示效果。 (2)、没有saveLayer的绘图流程 然后我们再来看

savelayer新建的画布上的图像做为目标图像,矩形所在的透明图层与之相交,计算结果画在新建的透明画布上。最终将计算结果直接盖在原始画布上,形成最终的显示效果。

(2)、没有saveLayer的绘图流程 然后我们再来看第二个示例,在第二个示例中,唯一的不同就是把saveLayer去掉了;
在saveLayer去掉后,所有的绘图操作都放在了原始View的Canvas所对应的Bitmap上了

Canvascanvascanvas); canvasColorcanvasdstBmpmPaint); mPaintPorterDuffXfermodecanvassrcBmpheightmPaint); mPaint

由于我们先把整个画布给染成了绿色,然后再画上了一个圆形,所以在应用xfermode来画源图像的时候,目标图像当前Bitmap上的所有图像了,也就是整个绿色的屏幕和一个圆形了。所以这时候源图像的相交区域是没有透明像素的,透明度全是100%,这也就不难解释结果是这样的原因了。
此时的xfermode合成过程如下:


由于没有调用saveLayer,所以圆形是直接画在原始画布上的,而当矩形与其相交时,就是直接与原始画布上的所有图像做计算的。
所以有关saveLayer的结论来了:
saveLayer会创建一个全新透明的bitmap,大小与指定保存的区域一致,其后的绘图操作都放在这个bitmap上进行。在绘制结束后,会直接盖在上一层的Bitmap上显示。

2、画布与图层 上面我们讲到了画布(Bitmap)、图层(Layer)和Canvas的概念,估计大家都会被绕晕了;下面我们下面来具体讲解下它们之间的关系。
来专门来画这个图形,比如我们上面在画矩形时的透明图层就是这个概念。
画布(bitmap):每一个画布都是一个bitmap,所有的图像都是画在bitmap上的!我们知道每一次调用canvas.drawxxx函数时,都会生成一个专用的透明图层来画这个图形,画完以后,就盖在了画布上。所以如果我们连续调用五个draw函数,那么就会生成五个透明图层,画完之后依次盖在画布上显示。
画布有两种:

第一种是view的原始画布,是通过onDraw(Canvas canvas)函数传进来的,其中参数中的canvas就对应的是view的原始画布,控件的背景就是画在这个画布上的!

函数以后,才会返回到原始画布上绘制。

;每一个draw函数都对应一个图层,在一个图形画完以后,就放在画纸上显示。而一张张透明的画纸则一层层地叠加在画板上显示出来。我们知道画板和画纸都是用夹子夹在一起的,所以当我们旋转画板时,所有画纸都会跟着旋转!当我们把整个画板裁小时,所以的画纸也都会变小了!
这一点非常重要,当我们利用saveLayer来生成多个画纸时,然后最上层的画纸调用canvas.rotate(30)是把画板给旋转了,所有的画纸也都被旋转30度!这一点非常重要。
另外,如果最上层的画纸调用canvas.clipRect()将画板裁剪了,那么所有的画纸也都会被裁剪。唯一能够恢复的操作是调用canvas.revert()把上一次的动作给取消掉!
但在利用canvas绘图与画板不一样的是,画布的影响只体现在以后的操作上,以前画上去的图像已经显示在屏幕上是不会受到影响的。
这一点一定要理解出来,下面会用到。
三、save()、saveLayer()、saveLayerAlpha()中的用法 1、saveLayer的用法 saveLayer的声明如下:

RectFboundsleftrightsaveFlags)

我们前面提到了saveLayer会新建一个画布(bitmap),后续的所有操作都是在这个画布上进行的。下面我们来分别看下saveLayer使用中的注意事项
(1)、saveLayer后的所有动作都只对新建画布有效 我们先看个例子:

ViewBitmapmBitmapContextcontextcontext,attrs); mPaint=newPaint(); mPaintColormBitmapgetResourcesCanvascanvascanvas); canvasmBitmapmPaintgetWidthcanvascanvasmPaint); canvaslayerID

效果图如下:


在onDraw中,我们先在view的原始画布上画上了小狗的图像,然后利用saveLayer新建了一个图层,然后利用canvas.skew将新建的图层水平斜切45度。所以之后画的矩形(0,0,150,160)就是斜切的。
而正是由于在新建画布后的各种操作都是针对新建画布来操作的,不会对以前的画布产生影响,从效果图中也明显可以看出,将画布水平斜切45度也只影响了saveLayer的新建画布,并没有对之前的原始画布产生影响。

(2)、通过Rect指定矩形大小就是新建的画布大小 在saveLayer的参数中,我们可以通过指定Rect对象或者指定四个点来来指定一个矩形,这个矩形的大小就是新建画布的大小,我们举例来看一下:

ViewBitmapmBitmapContextcontextcontext,attrs); mPaint=newPaint(); mPaintColormBitmapgetResourcesCanvascanvascanvas); canvasmBitmapmPaintmPaintcanvasmPaint); canvaslayerID

 

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

相关文章
  • HTML5 Canvas实现圆形并显示百分比的进度条实例详解

    HTML5 Canvas实现圆形并显示百分比的进度条实例详解

    2017-08-28 08:00

  • canvas一周一练 canvas基础学习

    canvas一周一练 canvas基础学习

    2017-08-27 16:00

  • UGUI初学习Canvas

    UGUI初学习Canvas

    2017-08-27 15:01

  • Canvas从入门到放弃(三)

    Canvas从入门到放弃(三)

    2017-08-27 12:01

网友点评