Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Apply ColorFilter but preserve transparent shadow in PNG file

I am applying a ColorFilter to a Drawable I wanted to know if's possible to change the color of a drawable but preserve the shadow in it.

Something like this:

enter image description here

Where if you applied something like:

view.getBackground().setColorFilter(new PorterDuffColorFilter(itemView.getResources().getColor(R.color.green_500), PorterDuff.Mode.SRC_IN);

It would apply that ColorFilter but preserve the shadow and alpha values.

How can I achieve this?

like image 342
AndyRoid Avatar asked Jan 29 '16 09:01

AndyRoid


2 Answers

I think that you need a hue shifter. If so, using the ColorFilterGenerator proposed in Understanding the Use of ColorMatrix and ColorMatrixColorFilter to Modify a Drawable's Hue you just need to do:

view.getBackground().setColorFilter(ColorFilterGenerator.adjustHue(180));

The result looks like this (hue rotated 180 degrees):

enter image description here

Note: All credit for this answer must go to @Richard Lalancette for his awesome answer to the question I linked

Update from the comments:

As you need to specify the target color, you can calculate the source and target HSV values and use the ColorFilterGenerator to shift the hue. For example:

// Your source color (The RGB color from your original image is 255,85,78)
float[] hsvSource = new float[3];
Color.RGBToHSV(255, 85, 78, hsvSource);

// The color whose hue you want to achieve (green for example)
float[] hsvTarget = new float[3];
Color.RGBToHSV(0, 200, 18, hsvTarget);

view.getBackground().setColorFilter(ColorFilterGenerator.adjustHue(hsvTarget[0] - hsvSource[0]));

Note that this approach only takes into account the hue values of the colors to shift it.

Update from the comments:

@Jared Rummler's wonderful answer (Understanding the Use of ColorMatrix and ColorMatrixColorFilter to Modify a Drawable's Hue) takes your drawable as a parameter so you don't need to specify the source color:

view.getBackground().setColorFilter(ColorFilterGenerator.from(view.getBackground()).to(Color.GREEN));
like image 162
antonio Avatar answered Nov 16 '22 22:11

antonio


The right (and probably only) way to achieve what you want is to split the drawable into multiple layers and use a layerDrawable to compose them. At that point you can have the color layer that you can change (and you wouldn't even need to use porter duff)

like image 1
Pasquale Anatriello Avatar answered Nov 16 '22 22:11

Pasquale Anatriello