小编典典

如何在 Android 中更改 Drawable 的颜色?

all

我正在开发一个 android 应用程序,并且我有一个从源图像加载的可绘制对象。在这张图片上,我想将所有白色像素转换为不同的颜色,比如蓝色,然后缓存生成的
Drawable 对象,以便以后使用。

例如,假设我有一个 20x20 的 PNG
文件,中间有一个白色圆圈,圆圈外的所有内容都是透明的。将那个白色圆圈变成蓝色并缓存结果的最佳方法是什么?如果我想使用该源图像创建几个新的可绘制对象(比如蓝色、红色、绿色、橙色等),答案会改变吗?

我猜我会想以某种方式使用 ColorMatrix,但我不确定如何。


阅读 64

收藏
2022-04-24

共1个答案

小编典典

我可以使用以下代码来做到这一点,该代码取自一个活动(布局非常简单,仅包含一个 ImageView,此处不发布)。

private static final int[] FROM_COLOR = new int[]{49, 179, 110};
private static final int THRESHOLD = 3;

public void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.test_colors);

    ImageView iv = (ImageView) findViewById(R.id.img);
    Drawable d = getResources().getDrawable(RES);
    iv.setImageDrawable(adjust(d));
}

private Drawable adjust(Drawable d)
{
    int to = Color.RED;

    //Need to copy to ensure that the bitmap is mutable.
    Bitmap src = ((BitmapDrawable) d).getBitmap();
    Bitmap bitmap = src.copy(Bitmap.Config.ARGB_8888, true);
    for(int x = 0;x < bitmap.getWidth();x++)
        for(int y = 0;y < bitmap.getHeight();y++)
            if(match(bitmap.getPixel(x, y))) 
                bitmap.setPixel(x, y, to);

    return new BitmapDrawable(bitmap);
}

private boolean match(int pixel)
{
    //There may be a better way to match, but I wanted to do a comparison ignoring
    //transparency, so I couldn't just do a direct integer compare.
    return Math.abs(Color.red(pixel) - FROM_COLOR[0]) < THRESHOLD &&
        Math.abs(Color.green(pixel) - FROM_COLOR[1]) < THRESHOLD &&
        Math.abs(Color.blue(pixel) - FROM_COLOR[2]) < THRESHOLD;
}
2022-04-24