2

在 J2ME 应用程序中加载图像的标准方法是使用 Image.createImage 方法,推荐的图像格式是 PNG。

现在,J2ME 规范没有对该方法的实现或图像在内存中的表示设置任何限制,因此每个供应商都有不同的实现。

特别是摩托罗拉有这个非常糟糕的实现,其中 PNG 在图像创建时被完全解码为 ARGB 字节数组。这意味着一个尺寸为 176x208 的 8K png 占用了大约 170K 的峰值内存来加载,而 Image 对象本身使用的内存大约是 145K!在诺基亚、索尼爱立信等其他手机上,相同的图像只需要大约 16K 即可加载和存储在内存中。我不知道他们使用了哪些智能优化,但出于某种难以理解的原因,摩托罗拉的 JVM 没有。

这对我的 J2ME 应用程序造成了严重破坏,几乎不可能在摩托罗拉手机上运行一个像样的版本。我尝试了各种解决方法,例如使用图像的 gzip'd ARGB 字节数组并在绘制过程中对其进行放气,但这会导致绘制速度减慢 10 倍!

有人知道这个问题的解决方法吗?J2ME 的开源 PNG 图像解码器具有摩托罗拉所缺乏的智能?或者是否可以对 PNG 图像进行一些操作以减少其内存占用?(我目前使用索引模式 PNG)欢迎任何指针..

高里

4

6 回答 6

3

关于索尼爱立信的一件事。不要给他们太多的信任。它们在加载图像时也会占用 (image_width x image_height x bytes_per_pixel) 内存。

来自 SE J2ME 开发人员文档,“所有图像都以每像素 16 位 RGB 格式存储在手机内存中,可能每个像素 alpha 通道具有 1 位或 8 位。 ”因此,至少 2 个字节。不同之处在于索尼爱立信手机(我不能代表诺基亚)有一个单独的内存块,用于在将图像加载到堆中之前先填充图像(您可以通过使用 Runtime.getRuntime().freeMemory 包装负载来查看这一点()...堆大小只会增加几个字节,这是新对象的大小)。

这并不是为摩托罗拉的手机辩护,因为我肯定在将 SE 手机移植到摩托罗拉手机时遇到了麻烦,但这并不是因为 SE 能够找到一种以更优化的方式将图像存储在堆中的方法。摩托罗拉只是将所有内容都存储在堆中,这就是您更快用完的原因。

较小的图像是一个好主意,不仅在解码器部分,而且从堆碎片的角度来看。它将允许图像适合较小的内存块而不是大的连续块。

于 2008-11-15T19:46:40.927 回答
1

好吧,在我看来,如果在创建图像时所有图像格式都立即解码为 ARGB 数组,那么您唯一真正能做的就是为您将用于显示内容的内存量创建一个上限屏幕。

您可以创建一个图像缓存,它将知道每个图像用于该特定设备的堆内存,加载和卸载图像是需要的。当然,这意味着依赖 Grabage Collector 可能无法让您的应用程序保持响应。

缓存管理可能需要在专用线程中进行。

如果您的应用程序屏幕足够静态而不需要太多动画,那么在任何给定时间只保留一个屏幕的图像加载可能会起作用。

还要记住 MIDP Canvas 通常不会自行重置。如果您使用 2 次不同的 Canvas.paint() 调用在屏幕的 2 个不同区域绘制 2 个不同的图像,您应该能够在实际图像对象被垃圾收集后很长时间保持显示这两个图像不要在它们上面画任何东西。

从纯粹的商业角度来看,您需要能够告诉您的客户,某些手机的 Java 实现非常糟糕,以至于您不会支持它们。

于 2008-11-06T10:50:52.653 回答
0

PNG往往是臃肿的。

为什么不使用 gif 来代替。

http://www.ddj.com/mobile/184406435;jsessionid=SBUQN2ECITM5OQSNDLOSKHSCJUNN2JVN?_requestid=76071

于 2008-11-05T15:23:19.330 回答
0

摩托罗拉开发者论坛建议您将较大的图像切割成较小的条带,然后一次性加载这些较小的条带而不是整个大图像。请注意,这不会减少图像的内存占用。这仍然需要所有条带的总和(宽度 * 高度 * 每像素字节数)。但它确实减少了解码 png 图像并加载它所需的内存。所以这就是我现在正在做的事情。它帮助了一些人。但是整体内存使用仍然是一个问题。

于 2008-11-10T13:43:04.693 回答
0

更好的解决方案是将 ARGB 存储为数据(使用某种索引来压缩它),并具有更改调色板等/无 PNG Header/ 的优点。而不是存储不同的PNG图像并使用createImage函数来创建图像。

于 2008-11-18T05:35:54.137 回答
0

减少 png 图像的一种方法是通过png gauntlet之类的程序运行它们 以减小其大小。

于 2009-04-27T14:41:47.390 回答