【发布时间】:2019-10-11 01:24:21
【问题描述】:
我想将位图(JPEG 图像)压缩到质量64,结果存储在字节数组中。以前我可以通过Bitmap#compress() 方法实现这一点:
public static byte[] compressJPEG(Bitmap bmp, int quality) {
if (quality <= 0)
return new byte[0];
byte[] array = new byte[0];
try {
ByteArrayOutputStream bmpStream = new ByteArrayOutputStream();
bmp.compress(Bitmap.CompressFormat.JPEG, quality, bmpStream);
array = bmpStream.toByteArray();
bmpStream.close();
} catch (Exception e) {
e.printStackTrace();
}
return array;
}
但是当我在不同的设备上运行它时,结果字节数组(具有相同的输入图像文件)是不同的。 (可能是因为它内部使用了nativeCompress())
检查后,我发现不同之处在于 Huffman 表、SOS 和图像数据部分,请参见: Diff check between 2 image photos
那么如何在不使用Bitmap#compress() 方法的情况下将JPEG 图像压缩到特定的质量级别?因为我真的希望结果字节数组在结构上相似。
【问题讨论】:
-
你必须自己写压缩算法或者使用跨平台库
-
@emandt 谢谢你回答我的问题,所以如果我想创建一个结构相似的压缩 JPEG 图像,我有两个选择:编写我自己的压缩算法,或者将整个图像传输到服务器处理并发送回 Android/iOS?
-
简而言之:是的。使用的算法可能会在每个操作系统次要/主要版本或实现中发生变化(即在索尼和三星设备之间),因此如果您期望“固定数据”,则不能使用它们。
-
正如您在另一个问题中提到的,我相信如果您使用固定表(量化表和霍夫曼表),您的方法将有效。您甚至不需要 SOS(但您需要图像尺寸来重新创建它)或 EOI,尝试捆绑 libjpeg 本机代码,并使用固定表进行编码。您可以在 "Abbreviated datastreams and multiple images" 中了解如何操作。
标签: java android image image-processing jpeg