Applying ColorFilter to ImageView with ShapedDrawable
Asked Answered
H

4

42

I have an ImageView with android:src set to a ShapedDrawable, namely a white circle. What I want is to colorize this ImageView in runtime responding to some events. imgView.setColorFilter seems to be solution, but after using this (tried different parameters) the image becomes invisible (I don't see it at the screen).

How to solve this? And are there better ways to have color circles?

Hodgson answered 11/4, 2012 at 21:42 Comment(4)
You might find this related Q&A interesting.Living
Sorry, but I couldn't find there anything related to this question.Hodgson
I'm not sure how you can't find the accepted answer related... Anyhow, here's another similar topic: link. As suggested there, try: imgView.setColorFilter( 0xff00ffff, PorterDuff.Mode.MULTIPLY );. If that doesn't suit your needs, a more sophisticated solution is also proposed there.Living
I've written, that setColorFilter doesn't work the way I expect: after applying it the image just disappears from the screen (leaving empty space there).Hodgson
L
109

Alright, I had a quick play with this and noticed your issue of the circles disappearing. Without you describing what exactly you tried, I assume you haven't tried setting the color filter to the Drawable itself yet? (as opposed to the ImageView, which only seems to work with BitmapDrawables).

The following statements work perfectly fine for an xml-declared ShapeDrawable with white as initial color:

ImageView redCircle = (ImageView) findViewById(R.id.circle_red_imageview);
ImageView greenCircle = (ImageView) findViewById(R.id.circle_green_imageview);
ImageView blueCircle = (ImageView) findViewById(R.id.circle_blue_imageview);

// we can create the color values in different ways:
redCircle.getDrawable().setColorFilter(Color.RED, PorterDuff.Mode.MULTIPLY );
greenCircle.getDrawable().setColorFilter(0xff00ff00, PorterDuff.Mode.MULTIPLY );
blueCircle.getDrawable().setColorFilter(getResources().getColor(R.color.blue), PorterDuff.Mode.MULTIPLY );

The ShapeDrawable for completeness: (I set the size on the ImageView, see below)

<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval" >
    <solid android:color="@android:color/white" />
</shape>

And one of the ImageViews as example:

<ImageView
    android:id="@+id/circle_red_imageview"
    android:layout_width="40dp"
    android:layout_height="40dp"
    android:padding="5dp"
    android:src="@drawable/circle_white" />

Visual result:

Screenshot of colored circles

Living answered 13/4, 2012 at 13:20 Comment(9)
calling mutable() on the Drawable will help keep state of drawables.Acaulescent
Wow this just saved me, you definitely want to apply the filter to the Drawable and not simply the ImageView.Ramburt
do we get the exact color we choose here setColorFilter(0xff00ff00, PorterDuff.Mode.MULTIPLY ) if we use white as original color. If not how can we get the exact color?Emelineemelita
@SadeepDarshana: I'm not sure what you're asking here? MULITPLY is imply defined as [Sa * Da, Sc * Dc], meaning that the result is composed of multiplying the source's alpha channel with the destination's, and the same for each of the colour channels (r, g and b). If you make either source equal to 1 (ignoring alpha channel for simplicity), then the result is 1 * Dc = Dc, which is just the destination channel. Vice versa, if destination equals 1, then it's just the source channel. The same math applies to the alpha channel.Living
got it thanks @Living but is Sa in the range of [0,255] or [0,1]? i mean for this should i use (white) or RGB(1 out of 255, 1 out of 255, 1 out of 255) as the original color to work as I expectedEmelineemelita
@SadeepDarshana: That would be [0,1], otherwise the multiplication operation (and many others) would make little sense. For more details on PorterDuff.Mode on Android, I'd suggest to have a read here or start a new question if you hit any snags.Living
@Living thanks, and I recommend MH.'s link for anyone interestedEmelineemelita
I had a PNG drawable for the ImageView and PorterDuff.Mode.SRC_IN worked correctly for me instead of PorterDuff.Mode.MULTIPLYChemurgy
@RahulChowdhury: Sure, depending on your use case you'll want to explore different modes. PorterDuff.Mode.MULTIPLY was just an example that fits the original question, and works because the initial colour of the circle is white. The point to take away here is how to apply a colour filter using one of the available PorterDuff.Mode options provided by the framework.Living
T
17

If you want to change Image Color use

PorterDuff.Mode.SRC_ATOP instead
PorterDuff.Mode.MULTIPLY

in above example.

Trimorphism answered 14/12, 2015 at 11:53 Comment(2)
I think author asked about any filter, not just SRC_ATOP or MULTIPLY.Eleusis
Right solution for image views with PNG sourceCeciliacecilio
C
8

You can use attribute android:tint in ImageView in xml.

Example:

<ImageView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:src="@drawable/your_drawable"
    android:tint="@color/your_color" />

Tested on Android 4.1.2 and 6.0.1

Cullin answered 25/11, 2016 at 15:14 Comment(1)
nice answer not need runMeet
D
0

You can do it very very simple using this library: https://github.com/jrvansuita/IconHandler

It will working like this:

Icon.on(yourImageView).color(R.color.your_color).icon(R.mipmap.your_icon).put();
Devitrify answered 14/3, 2017 at 11:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.