AndyRoid
AndyRoid

Reputation: 5067

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?

Upvotes: 6

Views: 1684

Answers (3)

Usama Saeed US
Usama Saeed US

Reputation: 1004

i was facing issue with transparent part of png and dropshadow, this code worked for me.

  // The colorPrimary is color you want to achieve 
    float colorRed = Color.red(colorPrimary) / 255f;
    float colorGreen = Color.green(colorPrimary) / 255f;
    float colorBlue = Color.blue(colorPrimary) / 255f;

    drawable.setColorFilter(new ColorMatrixColorFilter(new ColorMatrix(new float[]{
            1 - colorRed, 0,              0,             0,     colorRed * 255,
            0,            1 - colorGreen, 0,             0,     colorGreen * 255,
            0,            0,              1 - colorBlue, 0,     colorBlue * 255,
            0,            0,              0,             Color.alpha(colorPrimary) / 255f, 0,
    })));
    img.setImageDrawable(drawable);

Upvotes: 0

antonio
antonio

Reputation: 18262

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));

Upvotes: 3

Pasquale Anatriello
Pasquale Anatriello

Reputation: 2355

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)

Upvotes: 1

Related Questions