我正在将 bitmapData 编码为 JPG。什么是一个好的压缩率,可以在不损失整体图像质量的情况下产生更小的文件大小?(我正在寻找适用于任何图像的解决方案)
2 回答
所以,我试图以最理论上的方式回答你的问题,并解释为什么很难(如果不可能的话)推荐一个在所有情况下都能很好地工作的单一压缩率。
首先,您必须至少对有损压缩和无损压缩之间的区别有一个模糊的了解。
有损与无损
无损压缩是一种压缩算法,它采用一组数据,将其转换为另一组更小的数据。逆向过程应产生与预压缩数据完全相同的数据集。另一方面,有损压缩不会。
使用有损压缩,算法可以丢弃它认为重建原始消息不必要的信息,但不保证重建完全相同的消息。
让我们看一个假设的例子来说明这一点。假设我想出了一种压缩英文文本的算法方法。我有一个称为有损编解码器A
和一个有损编解码器称为B
. 假设我想压缩以下短语:
鲍勃去商店买牛奶了。
通过编解码器运行该短语A
,然后对其进行解压缩,我会得到:
鲍勃去商店买牛奶了。
B
但是,通过压缩率为 10 的编解码器运行相同的消息,我可能会得到以下短语:
鲍勃去商店买牛奶。
请注意,结果不一样,但非常接近。消息的完整性保持不变,但它与我放入系统的信息不同。
现在让我们通过B
压缩率为 5 的编解码器运行源消息。这次我尝试解码压缩消息时可能会得到以下信息:
鲍勃去商店买食物。
请注意,缺少更多信息,但消息的隐含意图仍然存在。但是我不知道,鲍勃去商店买什么样的食物。
最后,让我们通过B
压缩率为 1 的编解码器运行源消息。这次我可能会返回:
鲍勃不在这里。
这次算法决定 Bob 去了哪里并不重要,只是 Bob 不在当前位置。原始消息的核心意图仍然保留,但上下文的其余部分已丢失。
同样的理论也适用于图像。JPEG 压缩的工作原理是算法丢弃它认为不需要重建图像的数据。
那么JPEG如何真正起作用呢?
JPEG 实际工作的过程充满了复杂的数学,但在更高的层次上它很容易理解。它通过将图像分解成小的 8x8 像素块来工作。然后,它将这些像素从一组像素转换为一组数学公式(如果您有兴趣,可以使用DCT-II),然后通过分析这些公式,根据给定的压缩率查看可以省略哪些公式。
维基百科上的 DCT 文章中有一个很好的数学示例。
注意它是如何通过将一组简单的图案块(从余弦生成)混合在一起来构建字母“A”的图像的。
现在,你会注意到——如果你足够近距离地观察该图像——有一堆非常接近于零的系数,比如+0.006
和+0.021
。你会注意到,如果你仔细观察,它们对左侧最终图像的影响是相当小的。最简单的解释是:JPEG 压缩通过丢弃这些小值来工作,实际上不计算它们。因此,当它重构图像时,通过反转过程(iDCT/DCT-III),它不会对块添加或减去这些细微的变化。它只存储/使用对最终块影响最大的那些。
压缩率越低,它试图丢弃的这些越多。压缩率越高,它试图保持的越多。
现在在这个阶段有很多更微妙的数学,但这是最好的简单例子。
这是什么意思呢?!
这意味着压缩器尝试删除的信息直接取决于您尝试压缩的图像。由于块的结构和它们包含的信息,一些图像将比其他图像更容易压缩而不会显示视觉伪影。
还要考虑压缩的效果取决于谁在看它。我经常处理图像(无论是在大学还是在专业领域),并且花了很多时间研究 JPEG/MPEG 的底层压缩机制,因此我很容易发现压缩伪影,因为我知道我在寻找什么。但是,那些不那么敏锐的眼睛可能不会发现这些相同的文物。(就像有些人不能听 MP3 压缩文件,因为他们可以从字面上听到工作中的压缩算法)
因此,您的里程可能会有所不同,具体取决于您尝试执行的操作以及您尝试压缩的图像。如果您对基础数学有很好的理解,那么您可能能够根据您尝试压缩的图像预测在压缩比方面什么会给您带来最大的收益。但大多数时候,它只是实验的产物。
TL;博士
60% 到 80% 之间的压缩率通常可以很好地减小尺寸,而不会引入太多明显的视觉伪影。
您使用的压缩方式在很大程度上取决于图像以及您将使用它的目的。每当您将图像保存为 JPG 时,您都会失去永远无法恢复的质量,并且压缩率越高,您失去的质量就越多。
你需要问自己:
- 图像将如何使用?
- 它需要看起来多好?
- 我想节省空间吗?如果有,多少钱?如果不是,我对 JPG 压缩的目标是什么?
如果你有一堆大的、高分辨率的图像想要缩小以供网络使用,你最好调整图像的大小而不是降低质量。
如果我对您想要完成的工作以及您使用的图像类型有更多了解,我可以给您我的个人意见。最后,它确实取决于图像以及使用情况。