如何将位图着色为纯色

26

如何将位图着色为纯色,实际上是将所有 alpha > 0 的像素替换为给定的 RGB 值?此外,如何做到相同的效果,但保留每个像素的 alpha 值?我不希望使用逐像素操作,因为它们往往速度较慢。

我尝试使用 ColorMatrixColorFilter 和 ColorFilter,它们可以给位图上色,但会把颜色混合在一起而不是进行百分之百的着色。

4个回答

46

我通过使用PorterDuffColorFilter解决了这个问题。

Paint paint = new Paint();
paint.setColorFilter(new PorterDuffColorFilter(targetColor, PorterDuff.Mode.SRC_IN));
canvas.drawBitmap(resource, matrix, paint);

6
如果您想知道应该选择哪种“PorterDuff.Mode”,可以阅读一篇非常好的有关Porter-Duff规则的文章:http://www.ibm.com/developerworks/java/library/j-mer0918/ - tomrozb

41

仅为了给出更完整的答案。

这将接收一个位图并输出一个新的着色位图:

public static Bitmap tintImage(Bitmap bitmap, int color) {
    Paint paint = new Paint();
    paint.setColorFilter(new PorterDuffColorFilter(color, PorterDuff.Mode.SRC_IN));
    Bitmap bitmapResult = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Config.ARGB_8888);
    Canvas canvas = new Canvas(bitmapResult);
    canvas.drawBitmap(bitmap, 0, 0, paint);
    return bitmapResult;
}

2
颜色必须使用ARGB格式,例如color = 0xFF0000FF来使图像变成纯蓝色。如果您使用color = 0x0000FF,则会将图像设置为完全透明,因为alpha部分等于0x00。 - Mr-IDE
请确保传递ContextCompat.getColor(context, R.color.YOUR_COLOR)。 - SilverTech
由于某种原因,这会将绘制的位图向右和向下移动一个或两个像素,因此它的底部和右侧被剪切了。为什么会这样? - android developer

4

如果您的位图是一个可用于布局的drawable,那么您可以创建一个新的drawable(.xml),引用您的原始drawable(例如.png)。

<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
    android:src="@drawable/plus"
     android:tint="#2c53e5" />

0
Kotlin解决方案,因为将其他解决方案转换会导致位图结果被剪切的原因。
fun getTintedBitmap(inputBitmap: Bitmap, @ColorInt color: Int): Bitmap {
    val paint = Paint()
    paint.colorFilter = PorterDuffColorFilter(color, Mode.SRC_IN)
    val width = inputBitmap.width
    val height = inputBitmap.height
    val result = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
    val canvas = Canvas(result)
    canvas.drawBitmap(inputBitmap, null, Rect(0, 0, width, height), paint)
    return result
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接