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

例如,我有一个20x20的PNG文件,中间有一个白色的圆圈,圆圈之外的一切都是透明的。把白色圆圈变成蓝色并缓存结果的最好方法是什么?如果我想使用源图像来创建几个新的Drawables(比如蓝色、红色、绿色、橙色等),答案会改变吗?

我猜我想在某种程度上使用一个ColorMatrix,但我不确定如何。


当前回答

它适用于一些简单的绘图。我用它在一个简单的纯色矩形圆角形状和需要改变的颜色与不同的布局。

试试这个

android:backgroundTint="#101010"

其他回答

如果你有一个纯色的可绘制对象,你想把它改成不同的纯色,你可以使用ColorMatrixColorFilter。透明度得以保留。

int iColor = Color.parseColor(color);

int red   = (iColor & 0xFF0000) / 0xFFFF;
int green = (iColor & 0xFF00) / 0xFF;
int blue  = iColor & 0xFF;

float[] matrix = { 0, 0, 0, 0, red,
                   0, 0, 0, 0, green,
                   0, 0, 0, 0, blue,
                   0, 0, 0, 1, 0 };

ColorFilter colorFilter = new ColorMatrixColorFilter(matrix);
drawable.setColorFilter(colorFilter);

我可以用下面的代码做到这一点,这是从一个活动(布局是一个非常简单的,只包含一个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;
}

这段代码片段对我来说很有用:

PorterDuffColorFilter porterDuffColorFilter = new PorterDuffColorFilter(getResources().getColor(R.color.your_color),PorterDuff.Mode.MULTIPLY);

imgView.getDrawable().setColorFilter(porterDuffColorFilter);
imgView.setBackgroundColor(Color.TRANSPARENT)

你可以使用Android支持compat库来解决这个问题。:)

 // mutate to not share its state with any other drawable
 Drawable drawableWrap = DrawableCompat.wrap(drawable).mutate();
 DrawableCompat.setTint(drawableWrap, ContextCompat.getColor(getContext(), R.color.your_color))

你应该为所有api这样做:

Drawable myIcon = getResources().getDrawable( R.drawable.button ); 
ColorFilter filter = new LightingColorFilter( Color.BLACK, Color.BLACK);
myIcon.setColorFilter(filter);