在SurfaceView上加载和显示JPEG图片的最快方式是什么?

3
这是对我上一个问题的跟进:Canvas is drawing too slowly 现在,我能更快地绘制图像,但面临的问题是图像实际加载的时间太长。
在我正在开发的应用程序中,用户可以按顺序播放视频帧(jpegs),就好像他正在实时查看视频一样。我一直在使用BitmapFactory.decodeFile()将每个jpeg加载到位图中。由于有大约240个图像,我无法一次性加载所有图像,否则会耗尽我的堆空间。为了缩短每个图像显示的时间,我一直在通过单独的线程将最多6个预加载到数组中。
不幸的是,加载一张图像需要50到90毫秒的时间,而我需要每42毫秒显示一张图像。是否可能有更快的加载图像的方法?
为了澄清,这些图像在SD卡上的文件夹中,它们都是720x480的jpeg格式。我将它们采样为一半大小以减少内存使用。

你有没有注意到在使用内部存储器和使用PNG而不是JPEG时有什么区别? - mibollma
我还没有尝试过内部存储,我想下一步我会尝试一下。我最初使用的是png格式,但它们比jpeg格式大得多,而且这些jpeg格式已经占用了设备上约8MB的空间。 - BigFwoosh
使用内部存储似乎会快一些,但对于我正在做的事情来说仍然不够快。我认为我真正需要的是一种存储所有图像而不牺牲质量的方法。如果我将inSampleSize设置为4,我可以将它们全部存储在内存中,但质量会大幅下降。 - BigFwoosh
2个回答

1

我最终的实现方式与最初设想的有很大不同。虽然其中涉及了很多内容,但以下是我实现目标的要点:

  1. 所有图像都存储在SD卡上,并写入一个文件中(每个图像在文件中占用X字节)
  2. 使用本地代码从图像文件中读取和写入数据
  3. 请求图像时,我使用JNI包装器将图像列表中的索引和位图对象(RGB_565)传递给本地代码
  4. 本地代码锁定位图表面,直接将像素数据(作为uint8_t**)写入位图,然后解锁它
  5. 图像被渲染到屏幕上

通过这种方式,我只需要一次性在内存中存储一个图像,并且能够避免垃圾回收(因为位图只创建一次,然后在本地重新填充)。我希望其他人也能发现这种策略有用。


0

很遗憾,由于如今许多Android设备可以以高分辨率录制视频,但其屏幕尺寸较小,因此我将不得不调整图像大小。我也不能将这些图像作为资源引用,因为它们实际上是在设备上运行时从视频文件生成的。我想我可以考虑在生成图像时调整它们的大小。 - BigFwoosh

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