Android不规则图形(1)

1829 查看

前段时间有人问我关于怎么绘制不规则图形的问题。比如,如何像whatsApp那样绘制的聊天气泡图形。在这个系列文章中我们主要来关注一下如何实现不规则图形效果。

在开始之前,我必须承认我忽略了问我这个问题的这个人。如果您正在阅读这篇文章,那么请与我联系,我会为你记上一功。感谢您激发我写这一系列文章的灵感。

我们先从一个简单的不规则图形开始:一个带有圆角的矩形。有必要指出的是,圆角可以使用RoundRectShape Drawable实现(在API2.0里引入的)。但是,它不能实现之后我们要制作的所有效果,所以我们还是坚持使用自己的方法。

这里要使用的第一种技术就是我们在Styling Android介绍过的Dynamic Icons——使用Alpha遮罩层实现。

概念很简单,这里需要两张图片:第一张是我们需要显示在矩形中的图片,第二章是需要定义的矩形。然后我们使用一个Porter-Duff Alpha模式来进行图片结合。这个模式可以让我们从遮罩层中使用到透明像素的信息。

这是我们需要使用到的图片:

betty_sm

mask_sm

第一张是Betty,这篇文章的模特。第二张是定义圆角的遮罩层,这图片用绿色的原因是要保证遮罩层中的颜色不会被使用到(我们可不希望在转换的过程中让Betty变成绿色)。

代码很简单:

现在我们就创建了一张匹配了原图和遮罩层的新图片。首先就先绘制遮罩层图片,然后就把可爱的Betty绘制上去,使用一个带有SRC_ATOP的PorterDuffXFerMode模式的paint对象。这样就可以使用背景遮罩层的透明像素,进而就可以准确绘制原图了。结果就像这样:

part1

看起来非常不错,我们可以实现预期的结果了,但是这个方法还有一些问题。

首先,遮罩层的密度必须和原图一样,这点我们其实也可以对遮罩层进行缩放处理,但是缩放过度的话也会出现问题的。还有就是,如果原图和遮罩层的图比例不一样的话圆角也会出现变形。

还有一个大问题是,这样不够高效。为了实现这个效果,我们需要载入两张图片到内存中,然后结合成一张新的图片。如果图片很大的话,这样我们就有出现OutOfMemoryError的危险。

虽然这种技术还存在一些问题(比如不规则图形太复杂的话,用这种技术就有些困难了),但是还有会有解决方案的。这就是我们后面要说的,一种更高效的方式。我们在下一篇文章再见。

这篇文章的所有代码在这里