如何更快地加载 Android 位图?
How to load Android Bitmap faster?
我正在创建一个需要显示一系列 Bitmap
视频帧的应用程序。该应用程序使用 MediaCodec
将视频解码为多个帧,并获取每个帧的 Bitmap
s 以在 ImageView
上显示它们。
问题是每个Bitmap
的大小约为2~3MB(帧大小为1280 x 720,720p视频的大小。)所以当Bitmap数量超过60~65个时,应用会因为内存不足而崩溃。为了避免这个问题,我一直在实施 D 游览算法,它只加载 Bitmap
需要立即或很快显示的内容。基本上我一直在尝试这些方法。
1。提前加载所有Bitmap
。
它足够快,可以满足我的需要,但如前所述,当 Bitmap
的数量超过 60~65 时,应用程序会崩溃。
2。提取帧时,将每个帧保存到 JPEG
文件中,并在需要时将特定的 JPEG
加载到 Bitmap
中。
我用 BitmapFactory.decodeFile
从 JPEG
加载了 Bitmap
,但是速度很慢。
3。提取帧时,将整个帧保存到 MJPEG
文件中,并在需要时将特定的 "frame"(技术上是字节数组)加载到 Bitmap
s 中。
我想如果我从字节数组本身加载 Bitmap
性能可能会更好。因此,在提取帧时,我创建了另一个元数据文件,其中包含每个帧的字节索引信息,并在需要时使用该信息加载 Bitmap
s。 [BitmapFactory.decodeByteArray
](http://developer.android.com/reference/android/graphics/BitmapFactory.html#decodeByteArray(byte[], int, int)) 被使用。我可以看到速度略有提高,但仍然不够。
在这种情况下,我还能尝试什么来提高 Bitmap
加载?
你有几个选择,你的缓存想法很聪明。在我的脑海中,这里有一些尝试:
- 关注为什么你的图片这么大。该分辨率的图像应该能够压缩到小于 2 - 3 MB,如果可以将数据编码为更压缩的图像格式,它将大大减少应用程序的内存占用并导致更快的加载时间
- 如果并非总是需要全分辨率照片,您可以尝试按需调整大小,稍后,如果需要全分辨率照片,您可以加载它
- 在后台加载图像,这样当用户需要它们时,它们就已经存在了。这可以通过扩展您的适配器并在异步任务中加载图像来实现。 Google 示例中有一个很好的例子:
http://developer.android.com/training/displaying-bitmaps/process-bitmap.html
对于你的算法,一些库比如Glide and Picasso can handle that for you. As for the encoding/decoding speed, JPEG is probably your best bet at quickly flushing the Bitmap to disk because the file size is small and it could be backed by hardware。
您可以尝试的一些事情
- 如果您可以控制位图的生成方式,请使用 RGB565 来减少内存消耗(最多减少 50% 的内存,因为 ARGB8888 是 32 位,而 RGB565 是 16 位)
- 创建较小的图像,然后再按比例放大
- 将
android:largeHeap=true
添加到清单中,以便您有足够的内存来工作
- 位图的 LRU 缓存,这也已在 Picasso's caching 中实现
如果您愿意,可以根据您的特定需要手动编译您的 jpeg 库,但这需要非常繁重的工作。 something 您可以立即进行测试。
我正在创建一个需要显示一系列 Bitmap
视频帧的应用程序。该应用程序使用 MediaCodec
将视频解码为多个帧,并获取每个帧的 Bitmap
s 以在 ImageView
上显示它们。
问题是每个Bitmap
的大小约为2~3MB(帧大小为1280 x 720,720p视频的大小。)所以当Bitmap数量超过60~65个时,应用会因为内存不足而崩溃。为了避免这个问题,我一直在实施 D 游览算法,它只加载 Bitmap
需要立即或很快显示的内容。基本上我一直在尝试这些方法。
1。提前加载所有Bitmap
。
它足够快,可以满足我的需要,但如前所述,当 Bitmap
的数量超过 60~65 时,应用程序会崩溃。
2。提取帧时,将每个帧保存到 JPEG
文件中,并在需要时将特定的 JPEG
加载到 Bitmap
中。
我用 BitmapFactory.decodeFile
从 JPEG
加载了 Bitmap
,但是速度很慢。
3。提取帧时,将整个帧保存到 MJPEG
文件中,并在需要时将特定的 "frame"(技术上是字节数组)加载到 Bitmap
s 中。
我想如果我从字节数组本身加载 Bitmap
性能可能会更好。因此,在提取帧时,我创建了另一个元数据文件,其中包含每个帧的字节索引信息,并在需要时使用该信息加载 Bitmap
s。 [BitmapFactory.decodeByteArray
](http://developer.android.com/reference/android/graphics/BitmapFactory.html#decodeByteArray(byte[], int, int)) 被使用。我可以看到速度略有提高,但仍然不够。
在这种情况下,我还能尝试什么来提高 Bitmap
加载?
你有几个选择,你的缓存想法很聪明。在我的脑海中,这里有一些尝试:
- 关注为什么你的图片这么大。该分辨率的图像应该能够压缩到小于 2 - 3 MB,如果可以将数据编码为更压缩的图像格式,它将大大减少应用程序的内存占用并导致更快的加载时间
- 如果并非总是需要全分辨率照片,您可以尝试按需调整大小,稍后,如果需要全分辨率照片,您可以加载它
- 在后台加载图像,这样当用户需要它们时,它们就已经存在了。这可以通过扩展您的适配器并在异步任务中加载图像来实现。 Google 示例中有一个很好的例子: http://developer.android.com/training/displaying-bitmaps/process-bitmap.html
对于你的算法,一些库比如Glide and Picasso can handle that for you. As for the encoding/decoding speed, JPEG is probably your best bet at quickly flushing the Bitmap to disk because the file size is small and it could be backed by hardware。
您可以尝试的一些事情
- 如果您可以控制位图的生成方式,请使用 RGB565 来减少内存消耗(最多减少 50% 的内存,因为 ARGB8888 是 32 位,而 RGB565 是 16 位)
- 创建较小的图像,然后再按比例放大
- 将
android:largeHeap=true
添加到清单中,以便您有足够的内存来工作 - 位图的 LRU 缓存,这也已在 Picasso's caching 中实现
如果您愿意,可以根据您的特定需要手动编译您的 jpeg 库,但这需要非常繁重的工作。 something 您可以立即进行测试。