更快的位图转字节数组的方法

4

我不是Bitmap和Java的新手。我正在尝试在循环中将高分辨率位图转换为字节数组。请查看此处的代码:

ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 50, stream);
imageByteArray = stream.toByteArray();

当我使用上述方法时,我能够在1秒内转换5张图片。但是我需要更快的速度。我也尝试了像这样使用ByteBuffer的方法:

Bitmap bmp = intent.getExtras().get("data");
int size = bmp.getRowBytes() * bmp.getHeight();
ByteBuffer b = ByteBuffer.allocate(size);

bmp.copyPixelsToBuffer(b);

byte[] bytes = new byte[size];

try {
b.get(bytes, 0, bytes.length);
} catch (BufferUnderflowException e) {
// always happens
}

但是这很慢(比以前更慢):(
请问有更快的方法吗?指引我一下...

这个问题不是任何其他问题的副本。它与优化和寻找最佳技术有关。而且我已经做了相当好的研究。 - Ana
嘿,你可以分享一下你的发现吗?到目前为止,哪一个你分析出来是更快的? - Ganesh K
@vrs 的第一种方法更好。我刚刚发现,压缩得越多,花费的时间就越长。但是与后者相比,后者肯定需要更多的时间。 - Ana
3个回答

1
你必须考虑到处理速度与测试设备的速度密切相关(因为这是标记为android,我假设你正在使用移动设备)。你应该查看Android开发者关于如何有效处理大型位图 Android developers。因为每秒处理5张高分辨率图片对你来说很慢,我可以推测你有某种画廊或预览吗?如果是这样,你不应该处理高分辨率图片,确实应该查看上面的链接。此外,作为附注,你的第二段代码可以通过以下方式进行优化:
int bytes = bmp.getByteCount();
ByteBuffer buffer = ByteBuffer.allocate(bytes);
bmp.copyPixelsToBuffer(buffer);
byte[] array = buffer.array();

否则,我所知道的最有效的复制字节的方法是从Commons-IO中获取的copy()函数:
public static int copy(InputStream input, OutputStream output) throws IOException {
    int n, count = 0;
    byte[] buffer = new byte[4 * 1024];
    while (-1 != (n = input.read(buffer))) {
        output.write(buffer, 0, n);
        count += n;
    }
    return count;
}

我尝试了你提到的第一种方法。这并没有帮助,因为这种方法比我现在使用的方法(压缩技术)要慢10倍。但是我会再次查看这些链接。谢谢。 - Ana

1
第一种解决方案是正确的。
但这里可能发生两件事:
1. 图像可能不是JPEG类型,因此需要转换,这需要时间。 2. 图像被压缩了50%,这需要时间。
除此之外,如果它需要一些时间,我怀疑它能否更快(作为正确的解决方案)。

我通过调用ll.draw(Canvas)方法从LinearLayout中创建一个位图。哪种压缩方式最适合? - Ana
+1 感谢您的指导,但我在这个主题上还需要更多的帮助。过去两天以来,我一直没有头绪,真的已经搜索了很多资料。 - Ana
如果内存不是问题,您可以尝试在处理图像时不进行压缩,这将显着提高速度,并在保存到磁盘或SD卡时进行压缩。但是,如果您有大量图像,则可能会影响UI的性能,最终影响设备的性能。 - sokie
@sokie 是正确的。你可以做得更少来加快进程,但是无论如何处理和编写都需要一些时间。 - shkschneider

0

你可以尝试以下操作

Bitmap bitmap = intent.getExtras().get("data");
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap .compress(Bitmap.CompressFormat.JPEG, 100, stream);
byte[] byteArray = stream.toByteArray();

希望它能为你工作良好!!
请检查行 bitmap.compress(Bitmap.CompressFormat.JPEG, 50, stream)。因为你正在使用质量为 50 的 JPEG 格式,可能会引起问题。

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