Android中的ImageView有一个API可以用来动态合成新的图片,不需要额外的切图,即可更改图片的颜色:
public final void setColorFilter(int color) {
setColorFilter(color, PorterDuff.Mode.SRC_ATOP);
}
例如,我们有一个这样的黑色图片:
demo_image.png
布局:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
tools:context=".MainActivity">
<ImageView android:id="@+id/demoImg"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/demo_image"/>
</LinearLayout>
如果现在我们需要同样一张图片,但是色值改成#D81B60的该怎么办呢?
直接将上面的ImageView重新合成一下就可以了:
demoImg.setColorFilter(resources.getColor(R.color.colorAccent))
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorAccent">#D81B60</color>
</resources>
这样,黑色的图片就和新的颜色共同合成了一张红色的图片:
changed.png
这里的图像合成其实时候很多中模式的,这里默认使用了PorterDuff.Mode.SRC_ATOP模式。
public final void setColorFilter(int color) {
setColorFilter(color, PorterDuff.Mode.SRC_ATOP);
}
说到PorterDuff模式,这里要牵扯出两位计算机图形处理方面的两位科学家:Tom Porter和Tom Duff,正是得益于两位大神的工作才使得计算机图形图像处理变得如此丰富多彩。
Android中PorterDuff.Mode一共有15中之多,包含了各种合成规则,比如:
CLEAR: Destination pixels covered by the source are cleared to 0.
如果上面代码中使用了该模式的话,我们将得到一张空白的图片。因为原图片整个都被新的色值领域覆盖,从而导致它所有的像素全部清空。
在setColorFilter(...)这个方法中,PorterDuff.Mode中的the source代表新的色值领域,而Destination 则表示原始的图片。
再比如,刚才我们使用的默认模式:
SRC_ATOP: Discards the source pixels that do not cover destination pixels.Draws remaining source pixels over destination pixels.
正如注释描述的一样,该模式会忽略掉原图像素未被覆盖的部分,而将新的色值领域覆盖到两者共同的区域。即两者的交集部分将被新的色值覆盖,交集之外还是原图原来的样子。
这里有篇文章详细介绍了各种模式的合成效果:
逐一认识PorterDuff.Mode












网友评论