Ekulelu's Blog

iOS基于CoreGraphics的粗细可变且半透明笔画

在《iOS基于CoreGraphics的可变粗细的划线》的wiki上,已经介绍了现在使用CoreGraphics绘制可变粗细线条的方法,也就是每两个点就调用一次stroke方法绘制一条线段。这个在不透明的情况下没有问题,最多就是性能差点。但是你把绘制的颜色调节成透明的时候,你会发现一个很恶心的现象,一条线段变成了一节一节的。就像下图那样

为什么会变成这样呢?这牵扯到了iOS的线段绘制原理。它在绘制线段结尾的时候,有3中选择去填充这个头尾部:1、不做处理。2、画一个半圆。3、画一个和宽度距离相等的矩形。一般为了好看,我们都会选择第二种选项。因为我们每两个点就绘制了一条线段,所以结尾的点上会补充上一个半圆。当画第二条线段的时候,这条线段的起点洽是第一条线段的终端,所以第二条线段的头部半圆部分会重合在第一条线段里面,第一条线段尾部的半圆也会重合在第二条线段里面。由普通的混色规则所以出现了一个黑色圆。

尝试过更改线段尾部的模式来解决问题,但是行不通,两个相邻线段之间总是避免不了重合部分。也尝试过更改混合模式来解决这个问题。但是得出的效果并不是我想要的。

所以想到一种比较麻烦的办法:假设我需要绘制的颜色为(1,0,0,0.5)的半透明红色。先将这一笔绘制到另外一个drawingContext上,(destContext是最终绘制的图层),绘制的颜色为(1,0,0,1)的红颜色。然后将这一笔的图片导出,再将这张图片调节为需要的透明度之后,显示到原本的那张图片的上面。(也就是使用了两个大小和位置一样UIImage来展示)这样看起来就是在画带透明的颜色。过程如下图:

当这一笔画完之后,把这一笔的drawingContext导出成图片,然后将这样图片绘制到destContext上面,绘制的时候调节透明度为颜色的透明度。这样destContext就得到了透明的一笔。以后导出最终图片,导出destContext的图片就行了。过程如下: