鉴于PNG具有压缩参数,它如何无损?


156

据说PNG文件使用无损压缩。但是,每当我使用图像编辑器(例如GIMP)并尝试将图像另存为PNG文件时,它都会要求压缩参数,其范围在0到9之间。如果它的压缩参数会影响图像的视觉精度,压缩的图像,它如何使PNG无损?

仅当将压缩参数设置为9时,我才能获得无损行为吗?


40
大多数无损压缩算法都具有可调整项(如字典大小),这些可调整项概括为“在最小化输出大小方面应付出多少努力”滑块。这对ZIP,GZip,BZip2,LZMA,...有效
丹尼尔·B

20
这个问题可以用不同的方式陈述。如果压缩没有质量损失,那为什么不总是使用压缩最小的压缩呢?答案是,因为压缩和解压缩需要更多的RAM和更多的CPU时间。有时您想要更快的压缩率,而不在乎压缩率。
kasperd 2014年

14
PNG压缩几乎与ZIP文件相同。您可以或多或少地压缩它们,但是在解压缩时可以得到准确的文件,这就是无损的原因。
mikebabcock 2014年

13
大多数压缩软件(例如Zip和Rar)都允许您输入“压缩级别”,从而可以在更小的文件<->较短的时间之间进行选择。这并不意味着这些软件在压缩过程中会丢弃数据。此设置(在GIMP,pngcrush等中)相似。
Salman A

2
@naxa:真正的无损png没有任何警告。它始终是100%无损的。本文仅警告您某些旧浏览器在其PNG实施中存在的用于处理伽玛校正的错误。这仅在您需要将颜色与CSS颜色(未经伽马校正)匹配时才有意义。
Pauli L

Answers:


183

PNG是无损的。在这种情况下,GIMP很可能只是不使用最佳单词。可以将其视为“压缩质量”,换句话说,就是“压缩级别”。使用较低的压缩率,您可以获得较大的文件,但生成时间较短,而使用较高的压缩率,则文件较小,而生成时间更长。通常,在达到最高压缩级别时,收益会递减(即,与所需的时间增加相比,大小的减少不会那么大),但这取决于您。


42
另外,PNG压缩实际上具有许多可调参数,在其中任意方向上的调整都可以根据源的内容来缩小输出大小-它比简单的“更好”和“更差”滑块复杂得多。出于一般目的,它并不是太重要,但是如果您想要绝对的最小值,那么请使用类似的工具pngcrush可以比较许多变化以达到最小的可能。
鲍勃

4
较高的压缩级别会增加压缩时间,但是还会影响减压吗?
2014年

10
@Nolonar通常没有;如果有更高的压缩级别,通常会减少解压缩时间,因为需要读取和处理的数据更少。更长的压缩时间是由于更彻底地找到要压缩的模式(过度简化)所致。
蓬松的

1
@fluffy LordNeckbeard的答案的最高压缩解码时间比最低压缩时间长5倍。
安德烈Chalella

1
对于PNG,对于更好压缩的文件,较长的解压缩时间很常见的。问题在于,使用PNG,一个可能的技巧是,只要文件变小,就一遍又一遍地应用压缩算法。一旦大小增加,您就停止应用它。因此,很有可能您将压缩算法应用了5次或6次,这意味着您必须将文件解压缩5次或6次才能显示图像。
2014年

213

PNG已压缩,但无损

压缩级别是文件大小和编码/解码速度之间的权衡。为了过度概括,甚至非图像格式(例如FLAC)也具有类似的概念。

不同的压缩级别,相同的解码输出

尽管文件大小不同,但由于压缩级别不同,实际的解码输出将相同。

您可以使用MD5多路复用器比较解码输出的MD5哈希值。ffmpeg

最好通过一些示例显示:

创建PNG文件:

$ ffmpeg -i input -vframes 1 -compression_level 0 0.png
$ ffmpeg -i input -vframes 1 -compression_level 100 100.png
  • 默认情况下ffmpeg-compression_level 100用于PNG输出。

比较文件大小:

$ du -h *.png
  228K    0.png
  4.0K    100.png

解码PNG文件并显示MD5哈希值:

$ ffmpeg -loglevel error -i 0.png -f md5 -
3d3fbccf770a51f9d81725d4e0539f83

$ ffmpeg -loglevel error -i 100.png -f md5 -
3d3fbccf770a51f9d81725d4e0539f83

由于两个哈希值相同,因此可以确保解码后的输出(未压缩的原始视频)完全相同。


26
+1不知道ffmpeg可以处理png。
Lekensteyn 2014年

21
@Lekensteyn非常适合制作屏幕截图。跳过30秒并截取屏幕截图的示例:ffmpeg -ss 30 -i input -vframes 1 output.png同样适用于用图像制作视频,反之亦然。
llogan 2014年

这是否意味着PNG每次需要渲染时都需要解压缩?因为如果这是真的,我们必须是
akshay2000 2014年

如果您从磁盘或缓存中重新读取文件,是的,必须将其解压缩。在同一页面内,缓存可能可以重用解压缩的版本。
DavidMårtensson2014年

1
@ akshay2000取决于程序如何工作,从而渲染PNG。通常,从磁盘读取文件,将其解压缩并缓冲在RAM中。因此,只要将其缓冲在RAM中,就无需再次解压缩图像。
xZise 2014年

24

PNG压缩分为两个阶段。

  1. 预压缩会重新排列图像数据,以便通过通用压缩算法对其进行压缩。
  2. 实际的压缩由DEFLATE完成,DEFLATE通过使用短标记替换它们来搜索并消除重复的字节序列。

由于步骤2是一项非常耗时/耗费资源的任务,因此底层zlib库(原始DEFLATE的封装)采用的压缩参数范围为1 =最快压缩,9 =最佳压缩,0 =无压缩。这就是0-9范围的来源,GIMP只是将该参数向下传递给zlib。请注意,在0级时,您的png实际上会比等效的位图稍大。

但是,级别9只是zlib将尝试的“最佳”,仍然是一个非常妥协的解决方案
为了真正体会到这一点,如果您愿意在详尽的搜索上花费1000倍的处理能力,则可以使用zopfli而不是zlib来将数据密度提高3-8%。
压缩仍然是无损的,只是数据的最佳DEFLATE表示。这接近与zlib兼容的库的限制,因此是使用PNG可以实现的真正的“最佳”压缩。


2
注意:不管压缩级别或使用zopflipng时的迭代次数如何,解压缩时间都是相同的。
Adria 2014年

16

PNG格式的主要动机是创建GIF的替代品,该替代品不仅免费,而且在各个方面都对其进行了改进。结果,PNG压缩是完全无损的-也就是说,可以像GIF和大多数形式的TIFF一样,一点一点地精确地重建原始图像数据。

PNG使用两阶段压缩过程:

  1. 预压缩:过滤(预测)
  2. 压缩:DEFLATE(请参阅Wikipedia

预压缩步骤称为过滤,这是一种可逆地转换图像数据的方法,以便主压缩引擎可以更高效地运行。

举一个简单的例子,考虑字节序列从1到255均匀增加:

1, 2, 3, 4, 5, .... 255

由于序列中没有重复,因此压缩非常差或完全没有压缩。但是对序列的一个小小的修改(即,不保留第一个字节,而是用后面的字节和它的前任字节之间的差异替换每个后续字节),将序列转换为可压缩的集合:

1, 1, 1, 1, 1, .... 1

上面的转换是无损的,因为没有字节被省略,并且是完全可逆的。该系列的压缩大小将大大减少,但原始系列仍可以完美地重构。

实际的图像数据很少那么完美,但是过滤确实可以提高灰度和真彩色图像的压缩率,并且对某些调色板图像也有帮助。PNG支持五种类型的滤镜,编码器可以选择对图像的每一行像素使用不同的滤镜:

图片

该算法适用于字节,但是对于大像素(例如24位RGB或64位RGBA),仅比较相应的字节,这意味着像素颜色的红色分量与绿色和蓝色像素分量分开处理。

为了为每一行选择最佳的滤波器,编码器将需要测试所有可能的组合。这显然是不可能的,因为即使是20行的图像也需要测试超过95万亿个组合,其中“测试”将涉及对整个图像进行过滤和压缩。

压缩级别通常定义为0(无)和9(最佳)之间的数字。这些涉及速度和大小之间的权衡,并且涉及要尝试的行过滤器组合数量。关于这些压缩级别没有标准,因此每个图像编辑器可能都有自己的算法,这些算法可以在优化图像尺寸时尝试使用多少个滤波器。

压缩级别0表示根本不使用过滤器,这很快但很浪费。较高的级别意味着对图像行尝试了越来越多的组合,并且仅保留了最佳组合。

我猜想,最佳压缩的最简单方法是使用每个过滤器对每一行进行增量测试压缩,保存最小的结果,然后为下一行重复。这相当于对整个图像进行五次过滤和压缩,对于要多次传输和解码的图像而言,这可能是一个合理的权衡。根据工具开发者的判断,较低的压缩值将做更少的事情。

除过滤器外,压缩级别还可能影响zlib压缩级别,该级别介于0(无Deflate)和9(最大Deflate)之间。指定的0-9级别如何影响过滤器的使用(PNG的主要优化功能)仍然取决于该工具的开发人员。

结论是PNG具有一个压缩参数,可以极大地减小文件大小,而所有这些都不会损失单个像素。

资料来源:

Wikipedia便携式网络图形库
libpng文档第9章-压缩和过滤


1
我认为压缩级别设置不会更改过滤器的使用。级别1-9设置可能只是选择zlib压缩级别1-9,级别0表示根本不使用deflate算法。大多数实现可能不更改每行的筛选器,而始终使用路径筛选器。
Pauli L

@PauliL:我不同意,因为在所有PNG压缩软件的比较中,所生成图像的大小之间存在很大差异。如果所有产品对相同的库使用相同的参数,则所有大小和速度都应该相同。
harrymc

您是否有此类比较的链接?
Pauli L

@PauliL:对此比较结果进行了快速搜索。
harrymc

@PauliL:zlib压缩级别受PNG压缩级别影响可能是正确的。尽管没有压缩工具记录了它们的确切功能,但我还是相应地修改了答案。可能导致结果最差的工具的解释是,它们根本不使用任何过滤器,而仅使用zlib压缩。
harrymc

5

好的,我来不及获得赏金,但是无论如何这是我的答案。

PNG总是无损的。它使用Deflate / Inflate算法,类似于zip程序中使用的算法。

Deflate算法搜索重复的字节序列并将其替换为标签。压缩级别设置指定程序用于查找字节序列的最佳组合的工作量,以及为此预留的内存量。这是时间和内存使用量与压缩文件大小之间的折衷。但是,现代计算机是如此之快,并且具有足够的内存,因此除了最高压缩设置外,几乎不需要使用其他任何东西。

许多PNG实现使用zlib库进行压缩。Zlib具有九个压缩级别,即1-9。我不知道Gimp的内部原理,但是由于它的压缩级别设置为0-9(0 =无压缩),因此我认为此设置只是选择zlib的压缩级别。

Deflate算法是一种通用的压缩算法,尚未设计用于压缩图片。与大多数其他无损图像文件格式不同,PNG格式不限于此。PNG压缩利用了我们正在压缩2D图像的知识。这是通过所谓的过滤器实现的。

(过滤器在这里实际上是一个误导性术语。它实际上并没有改变图像内容,只是对其编码方式不同。更准确的名称是增量编码器。)

PNG规范指定5种不同的过滤器(包括0 =无)。过滤器将绝对像素值替换为前一个像素与左,上,对角线或它们的组合之间的差。这可以显着提高压缩率。图像上的每条扫描线可以使用不同的滤镜。编码器可以通过为每条线选择最佳滤波器来优化压缩。

有关PNG文件格式的详细信息,请参见PNG规范

由于实际上组合的数量是无限的,因此无法尝试所有组合。因此,已经开发出不同种类的策略来找到有效的组合。大多数图像编辑器可能甚至没有尝试逐行优化滤镜,而是仅使用固定滤镜(最有可能是Paeth)。

命令行程序pngcrush尝试几种策略来找到最佳结果。它可以大大减少其他程序创建的PNG文件的大小,但是在较大的图像上可能会花费很多时间。请参见Source Forge-pngcrush


3

无损内容中的压缩级别始终只是交换编码资源(通常是时间,有时还包括RAM)与比特率之间的关系。质量始终是100%。

当然,无损压缩机永远不能保证任何实际的压缩。随机数据是不可压缩的,没有可寻找的模式,也没有相似性。香农信息论及所有其他。无损数据压缩的全部要点是,人们通常使用高度非随机的数据,但是对于传输和存储,我们可以将其压缩到尽可能少的位。希望尽可能接近原始的Kolmogorov复杂性

无论是zip还是7z通用数据,png图像,flac音频或h.264(无损模式)视频,都是一样的。对于某些压缩算法,例如lzma(7zip)和bzip2,提高压缩设置将增加DECODER的CPU时间(bzip2),或者更多时候只是所需的RAM数量(lzma和bzip2,以及具有更多参考帧的h.264)。 。通常,解码器必须将更多的解码输出保存在RAM中,因为解码下一个字节可能是指许多兆字节之前解码的字节(例如,与半秒前的视频帧最相似的视频帧将使用对12帧的引用进行编码。 )。与bzip2相同,选择较大的块大小,但解压缩速度较慢。 lzma具有可变大小的字典,您可以制作需要1的文件。


嗯,我看到了一种实现对步进电机和机头直接控制的实现,以提供有保证的无损压缩。如果您有高分辨率时钟源,则很容易击败曼彻斯特编码。
2014年

@约书亚:使用更高密度的物理存储格式与数据压缩不一样……
SamB 2014年

0

首先,PNG始终是无损的。明显的悖论是由于存在两种可能的压缩方式(对于任何类型的数据):有损和无损。

无损压缩使用各种技巧来压缩数据(即文件大小),从而保留所有内容且不做任何近似。结果,无损压缩实际上可能根本无法压缩所有内容。(从技术上讲,对于无损方法,具有高熵的数据可能很难压缩,甚至无法压缩。) 有损压缩近似于实际数据,但是近似并不完美,但是这种“丢弃”的精度通常可以实现更好的压缩。

这是一个无损压缩的简单示例:如果您的图像由1,000个黑色像素组成,则可以存储一个计数(1000)和一个值(黑色),而不是存储1000次黑色值,从而压缩1000个像素,图片”分成两个数字。(这是一种称为游程长度编码的无损压缩方法的粗略形式)。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.