【问题标题】:Huge spike in memory consumption when using png with lot of transparent area使用具有大量透明区域的 png 时,内存消耗会急剧增加
【发布时间】:2017-02-17 09:05:17
【问题描述】:

我在我的应用程序中使用带有 png 背景按钮 用于 CopyToClipboard 功能(在各种片段中使用了大约 6-7 次)。由于图像应该很小出于我的目的,我通过在图像周围放置额外的透明区域来增加图像的面积,以便我可以增加按钮可点击区域的大小,但图像要小(我知道它效率不高,从那以后我设计了更好的方法来实现这一点)。

我后来在上传一些其他图像(大约 150kb 大小的大图像)时注意到了巨大的峰值,并且经过大量调试(我的意思是很多!)我发现问题不是由于更大的图像,但由于 CopyToClipboard 图像的大小仅为 8kb !!!改回旧的 CopyToClipboard 图像(具有较小的透明区域)使内存消耗恢复正常。

我的问题是 为什么会发生这种情况?对于这样一个小图像来创建如此巨大的峰值(比之前的内存消耗增加了一倍)并使应用程序变慢,真是令人费解。

如下图所示:白色区域是透明区域。我的按钮尺寸:15dp x 15dp。

我再说一遍,我的问题是 为什么会这样?因为我已经解决了这个问题,所以这不是解决方案。

【问题讨论】:

    标签: android image memory png


    【解决方案1】:

    你的图像在磁盘上只有 7-8KB 并不重要,因为它在解码时会占用更多的内存。

    显然,大透明区域可以有效地编码在 PNG 文件中,因此图像具有那么小尺寸。 但实际上它的尺寸是 (600 x 745),所以在内存中大概需要 (600 * 745 * 4) 字节,加上一些元信息,所以将近 2 兆字节。 4 乘数代表使用 Alpha 通道对颜色进行编码所需的字节数。 Android Bitmaps 在内部由线性一维整数数组表示,因此您可以想象系统需要分配一个大小为 600 * 745 = 447000 的数组来创建您的 Bitmap。

    这就是为什么这么简单的图像内存消耗如此之高的原因。

    【讨论】:

    • 我有一种预感,这可能与分辨率有关。基本上你是在告诉我这个尖峰的发生是因为图像的分辨率太高,并且它在位图中的内部存储带来了这种效果对吗?
    • @KaushikNP,基本上,是的。但这不是 Android 或 Bitmap 的错,这只是位图在内存中的表示方式——作为原始像素数组。在磁盘上,它们被表示为有效编码的结构,因此它们占用的空间要少得多。
    • 谢谢 Dimezis。事实上,两幅图像的分辨率都有很大差异,所以这似乎很有可能。我犯的错误是没有考虑位图的分辨率,而只是检查了大小。
    猜你喜欢
    • 2019-04-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-24
    • 1970-01-01
    相关资源
    最近更新 更多