-1

I am using a few of the stock Android resources, such as ic_menu_camera.png:

enter image description here

The images have a transparent background (desired), but also some transparency in the coloured pixels, too (undesired).

I'm using a ColorMatrixColorFilter to apply a tint to these images and that's working fine, however, the small amount of transparency in the icons is causing the underlying background to bleed through, and fading the colour. I can't figure out a programmatic way to set all coloured pixels to be opaque. Any help?

Current colouring code:

public static void colorImageView(Context context, ImageView imageView, @ColorRes int colorResId) {
    Drawable drawable = imageView.getDrawable();
    int color = context.getResources().getColor(colorResId);

    drawable.setColorFilter(new ColorMatrixColorFilter(new ColorMatrix(new float[] {
            0, 0, 0, 0, Color.red(color),
            0, 0, 0, 0, Color.green(color),
            0, 0, 0, 0, Color.blue(color),
            0, 0, 0, 1, 0,
    })));
}

Current result:

enter image description here

(first icon's source image is opaque, whereas the other 3 have undesired transparency, leading to this off-blue colour)

Alexander
  • 59,041
  • 12
  • 98
  • 151
  • 1
    Why not just convert the images using some desktop tool and package the corrected images in your app? Note that what you're trying to do may well be possible, but unless you need N different colors of images, I don't know what you're gaining by doing it on the fly. – CommonsWare Aug 30 '14 at 23:18
  • Because there are like 10 icons that I need, each one in 5 resolutions, and 2 colours. That's 100 images. Plus using the built in res grants automatic forward compatibility. :/ – Alexander Aug 30 '14 at 23:24
  • 1
    "Plus using the built in res grants automatic forward compatibility" -- not really. Either you are copying the icons from the SDK into your project, or you are not. If you are, then you gain consistency but lose forward compatibility. If, instead, you are using `android.R.drawable` references, then you have no idea if your algorithm will look decent on any given device (as there's nothing stopping a manufacturer from tinkering with those images), let alone in future versions of Android (e.g., whatever L turns into). – CommonsWare Aug 30 '14 at 23:27
  • try increasing the "s" value (now 1 in the last matrix row) – pskink Aug 31 '14 at 06:43

1 Answers1

2

A very simple approach came to my mind first: Maybe you could convert the Drawable into a Bitmap and perform the desired pixel operations (like in this answer), e.g:

for(int x = 0; x < bitmap.getWidth(); x++) {
    for(int y = 0; y < bitmap.getHeight(); y++) {
        int pixel = bitmap.getPixel(x, y);
        int r = Color.red(pixel), g = Color.green(pixel), b = Color.blue(pixel);
        if (r != 0 || g != 0 || b != 0)
        {
            pixel.setPixel(x, y, Color.rgb(r, g, b));
        }
    }
}

to delete any alpha channel value in each pixel with an r-, g- or b-value higher than zero.

But I dont know, how poor or slow this approach works. I think the conversion into a bitmap with pixel operations might be much slower than a ColorMatrixColorFilter.

Community
  • 1
  • 1
Lukas Körfer
  • 13,515
  • 7
  • 46
  • 62
  • I was considering this, it's not the neatest fix, but I'll resort to it if I have to. – Alexander Aug 30 '14 at 23:31
  • You could combine it with 'CommonsWare's idea and use this in a small java desktop tool to get the desired icons before adding them to the app. – Lukas Körfer Aug 30 '14 at 23:35
  • Ultimately this app will be a part of a skinnable platform, so the dynamic nature would be a really nice thing to have. – Alexander Aug 30 '14 at 23:38
  • 1
    Upvote from me. I was about to post something similar. My recommendation would be to change the `if (r != 0 || g != 0 || b != 0)` expression to `if (Color.alpha(pixel) != 0)` because there's no guarantee that the transparent pixels are RGB(0,0,0). You can also experiment with `if (Color.alpha(pixel) > X)` where `X` is some threshold constant – selbie Aug 31 '14 at 02:26
  • But that would not solve his problem. He wants the transparent part in the background, but not in the coloured parts. – Lukas Körfer Aug 31 '14 at 09:19