15

I am trying to display the transparent GIF image in my app with no success. I can get to download and display the icon in an ImageView but with white background instead of transparent.

I have already tried these solutions with no sucess: Convert GIF to PNG programatically

Has anyone figured out how to display the GIF image with transparency? I am using the Android 18 SDK.

Community
  • 1
  • 1
netcyrax
  • 1,079
  • 1
  • 13
  • 27
  • 2
    [Here](https://code.google.com/p/android/issues/detail?id=62016) is a bug report that describes the problem. Not sure if Google plans to fix it. Maybe staring it will help. – paul Nov 18 '13 at 19:29
  • Thanks Paul, i have already stared it! But even if i use an earlier SDK than the 4.4, the same problem still occurs. – netcyrax Nov 18 '13 at 19:45
  • It should be based on the version of android on your device rather than the SDK you build against. Are you testing on a 4.4 device? I have a workaround which I will post shortly. – paul Nov 18 '13 at 20:01
  • Yes, you are absolutely right. I was using a 4.4 device. I just tried the same code in a 4.3 emulator and the transparency worked fine. I am waiting for your workaround :) Thanks again. – netcyrax Nov 18 '13 at 20:18

3 Answers3

19

Here is a workaround that has worked for me. It is not a good solution. It may not work in all cases and there is significant overhead in image processing. Hopefully someone else will find a better solution.

In my testing, GIF images in 4.4 have transparency values as either white (-1) or black (-16777216). After you load a Bitmap, you can convert the white/black pixels back to transparent. Of course this will only work if the rest of the image doesn't use the same color. If it does then you will also convert parts of your image to transparent that were not transparent in the original image. In my case this wasn't a problem.

You can use the following code to convert either white or black pixels to transparent.

Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
bitmap = eraseBG(bitmap, -1);         // use for white background
bitmap = eraseBG(bitmap, -16777216);  // use for black background


private static Bitmap eraseBG(Bitmap src, int color) {
    int width = src.getWidth();
    int height = src.getHeight();
    Bitmap b = src.copy(Config.ARGB_8888, true);
    b.setHasAlpha(true);

    int[] pixels = new int[width * height];
    src.getPixels(pixels, 0, width, 0, 0, width, height);

    for (int i = 0; i < width * height; i++) {
        if (pixels[i] == color) {
            pixels[i] = 0;
        }
    }

    b.setPixels(pixels, 0, width, 0, 0, width, height);

    return b;
}

Note: I had to copy the Bitmap to a new ARGB_8888 image for this to work. Even when loading the bitmap as mutable, I still couldn't modify the pixels. This is partly why there is so much overhead.

paul
  • 795
  • 1
  • 7
  • 19
  • I don't know. You would have to try it. – paul Aug 08 '15 at 21:36
  • I rather think it doesn't – Mooing Duck Aug 05 '16 at 22:32
  • @paul This is a good answer, however, in my case, images seem to use different background colors for transparency, some have a pink background, some cyan, some black and others have a black background with a small white box around the image itself and somehow transparency is rendered correctly in API >23 and browsers. I'm guessing this is because the header contains that info. Is there a workaround for this (thousands of images I have no control over)? Asking here before making a new question. – Galarzaa90 Sep 07 '16 at 16:05
  • The transparency info is there in the image and it doesn't show correctly because of an Android bug. It works correctly in API 23+ because they fixed the bug. I still apply this workaround for API 19-22. I'm not really sure if you can make it work somehow. – paul Sep 15 '16 at 18:53
  • It's really helpfull dude! – Acuna Sep 25 '18 at 11:18
4

You can use GIMP (opern source GNU software) to convert a GIF to PNG. Install the software, open the GIF, then export it as a PNG.

Peri Hartman
  • 19,314
  • 18
  • 55
  • 101
2

You can use GifDecoder from android-gifview instead of BitmapFactory to decode GIFs:

GifDecoder gd = new GifDecoder();
gd.read(new FileInputStream(filename));
return gd.getBitmap();

It works for me.

Zhiyong
  • 726
  • 7
  • 15
  • kord it's not, because it using a side monstrous library for what can be done with about 10 strings (refer a @paul answer). – Acuna Sep 25 '18 at 11:14
  • This is THE solution, if the image contains transparent and white/black pixels. Then paul's answer is not useful. The GifDecoder library is not monstrous (16KB). – C. Ecker Apr 04 '19 at 23:36
  • But the BitmapFactory is faster. Use the GIFDecoder only when necessary (API 19-22). – C. Ecker Apr 05 '19 at 00:03