在Android ImageView中使用透明GIF

15
我试图在我的应用中显示透明的GIF图像,但没有成功。我可以通过ImageView下载和显示图标,但背景是白色而不是透明的。
我已经尝试过这些解决方案,但都没有成功:将GIF转换为PNG 有人找到了如何显示带透明度的GIF图像吗?我正在使用Android 18 SDK。

2
这里是一个描述问题的错误报告。不确定Google是否计划修复它。也许关注它会有所帮助。 - paul
谢谢Paul,我已经开始了!但是即使我使用比4.4更早的SDK,仍然会出现同样的问题。 - netcyrax
它应该基于您设备上的Android版本而不是您构建的SDK。您正在测试4.4设备吗?我有一个解决方法,很快就会发布。 - paul
是的,你完全正确。我正在使用一台4.4的设备。我刚刚在一个4.3的模拟器中尝试了相同的代码,透明度正常运行。我正在等待您的解决方法 :) 再次感谢。 - netcyrax
3个回答

19

这是一项对我有效的解决方法。虽然它并不是一个好的解决方案,而且在图像处理中存在显着的开销,也不能适用于所有情况。希望其他人能够找到更好的解决方案。

在我的测试中,4.4版本的GIF图像具有白色(-1)或黑色(-16777216)的透明值。加载位图后,您可以将白/黑像素转换回透明。当然,如果图像的其余部分使用相同的颜色,则只有在此情况下才能起作用。如果是这样,您还将把原始图像中不透明的部分转换为透明。在我的情况下,这并不是一个问题。

您可以使用以下代码将白色或黑色像素转换为透明。

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



(Note: This is already in Chinese, so there's no need for me to translate it.)
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;
}

注意:为了使这个工作,我不得不将Bitmap复制到一个新的ARGB_8888图像中。即使将位图加载为可变的,我仍然无法修改像素。这部分是为什么会有这么多开销的原因。


我不知道。你得试一下。 - paul
我认为它不是这样的。 - Mooing Duck
@paul 这是一个很好的回答,但在我的情况下,图像似乎对透明度使用不同的背景颜色,有些有粉色背景,一些青色,一些黑色,还有一些有黑色背景,周围有一个小白框。在API>23和浏览器中,透明度正确呈现。我猜这是因为标题包含了那些信息。是否有解决方法(成千上万的我无法控制的图像)?在发新问题之前在此询问。 - Galarzaa90
图像中存在透明度信息,但由于 Android 的一个 bug,它无法正确显示。在 API 23+ 中,它可以正常工作,因为他们修复了这个 bug。对于 API 19-22,我仍然使用这个解决方法。我不确定你是否能够以某种方式使其正常工作。 - paul
这真的很有帮助,伙计! - Acuna

4
您可以使用GIMP(开源GNU软件)将GIF转换为PNG。安装该软件,打开GIF文件,然后将其导出为PNG格式。

1
我无法这样做,因为我正在使用从网站下载的GIF图像(我无法控制该网站)。 - netcyrax
为什么我没想到呢?当然,转换图片!点赞! - Jose Manuel Abarca Rodríguez

2

你可以使用android-gifview中的GifDecoder解码GIF图像,而不是使用BitmapFactory:

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

对我来说它有效。


kord不是这样的,因为它使用了一个庞大的库来完成只需要大约10个字符串就能实现的功能(参考@paul的回答)。 - Acuna
如果图像包含透明和白/黑像素,则这是解决方案。那么Paul的答案就没有用了。GifDecoder库不是庞大的(16KB)。 - C. Ecker
但是 BitmapFactory 更快。只有在必要时才使用 GIFDecoder(API 19-22)。 - C. Ecker

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接