Android API提供了用于保存位图对象的Bitmap.compress(format, quality, output)
方法。我创建了一个示例应用程序,该应用程序将jpeg图像(有些嘈杂的相机照片)加载到位图中,然后将其压缩回相同的文件。然后,再做5次。
很显然,我的位图累积了压缩伪像。对我来说令人惊讶的是,这些伪像的数量取决于怪异的压缩质量。当我将质量设置为100(我希望这是最好的质量)时,工件明显可见。当我将质量降低到90时,伪像明显不那么可见。 80的质量设置给我最好的结果。质量设置为70以下时,图像会迅速退化。
当我以100质量压缩位图时,每次通过时,生成的文件大小都会线性增加。对于90和80的质量设置,每次通过时生成的文件大小都保持不变。
我已经在Android 5设备(HTC One)和Android 6设备(Motorola Moto G)上测试了此行为,并且非常一致。不过,在Android 7上,(三星S7)我无法在结果图像中发现任何差异。
所以,我的问题是为什么质量= 80的压缩比质量= 90尤其是质量= 100的压缩效果更好。我真的希望保存质量为100的图像几乎是无损的(例如,例如, GIMP)
答案 0 :(得分:1)
不看示例很难说,但我假设您注意到的伪像是高频分量(其特征是亮度急剧陡峭变化,仅持续一两个像素)。尽管不是强制性的,但许多.jpeg压缩算法将使用特定的quantization matrices,它们会在较低的质量设置下衰减高频分量 more ,从而为低频分量留出空间您可能会认为对图片更“基本”的东西。
因此,不难想象,在较低的质量设置下,高频分量将被“切出”图像,降低了梯度并产生了整体“平滑”的外观。而且,不难想象,由于质量高(但不完美),在连续运行中某些高频成分可能会被放大甚至放大(由于量化误差)。
换一种说法,JPEG宏块由以下8x8图元的线性组合组成,并且在较低的质量设置下,不太可能出现靠近右侧和底部的图元,因此:没有锐利的边缘。 / p>
(来自Wikimedia的原始图片,see here)
答案 1 :(得分:0)
JPEG是一种有损压缩算法。即使您使用100%的质量,解码后的图像也不会与原始图像相同。因此,如果您要对同一张图像进行多次编码和解码,那么通常会发现伪像。
如果您不希望有任何损失,请使用PNG算法。
我的回答有点不完整,因为80%的质量不应该超过100%,如果您遇到这种情况,我不知道为什么。
使用Photoshop或GIMP进行编码时,无法观察到丢失,可能是因为它们改进了算法。在Android 7中比在较低版本中获得更好的结果也可能是相同的结果。