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

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

评论

大多数无损压缩算法都具有可调整项(如字典大小),这些可调整项概括为“在最小化输出大小上应付出多少努力”滑块。这适用于ZIP,GZip,BZip2,LZMA,...

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

PNG压缩几乎与ZIP文件相同。您可以或多或少地压缩它们,但是在解压缩时可以得到准确的文件,这就是使文件无损的原因。
大多数压缩软件(例如Zip和Rar)允许您输入“压缩级别”,从而可以在更小的文件<->较短的时间之间进行选择。这并不意味着这些软件在压缩过程中会丢弃数据。此设置(在GIMP,pngcrush等中)相似。

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

#1 楼

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

评论


而且,PNG压缩实际上具有许多可调参数,其中,在两个方向上的调整都可以根据源的内容来缩小输出大小-它比简单的“更好”和“更差”滑块复杂得多。出于一般目的,它并不是太重要,但是如果您想要绝对的最小值,请使用pngcrush之类的工具,该工具可以比较许多变化形式,以实现最小的可能。

–鲍勃
2014年11月27日,下午3:32

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

– Nolonar
2014年11月28日在8:06

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

–蓬松
2014年11月29日在7:15

@fluffy LordNeckbeard的答案具有最高的压缩比最低的压缩时间长5倍。

–AndréChalella
2014年12月2日在2:07

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

–吗?
2014年12月5日上午11:16

#2 楼

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


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

评论


+1不知道ffmpeg可以处理png。

– Lekensteyn
2014-11-27 21:49

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

– llogan
2014年11月27日23:16

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

–akshay2000
2014年11月28日在9:25

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

– DavidMårtensson
2014年11月28日9:56



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

–xZise
2014年11月29日在2:33

#3 楼

PNG压缩分为两个阶段。


预压缩会重新排列图像数据,以便通过通用压缩算法可以更容易地压缩。
实际压缩是由DEFLATE完成,该任务通过用短标记替换来查找并消除重复的字节序列。

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

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

评论


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

– Adria
2014年11月28日上午10:05

#4 楼

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

PNG使用2级压缩压缩过程:


预压缩:过滤(预测)
压缩:DEFLATE(请参阅维基百科)

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

作为一个简单示例,请考虑将字节序列从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 Portable Network Graphicslibpng文档第9章-压缩和过滤

评论


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

–Pauli L
2014年11月30日13:20

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

–harrymc
2014年11月30日14:22



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

–Pauli L
2014年11月30日15:10

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

–harrymc
2014年11月30日在16:13

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

–harrymc
2014年12月1日12:12



#5 楼

好的,我为赏金而为时已晚,但是无论如何,这就是我的答案。

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

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

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

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

(过滤器在这里实际上是一个误导性术语。它实际上并没有改变图像的内容,只是对它进行了编码。 delta编码器。)

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

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

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

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

#6 楼

无损内容中的压缩级别始终只是交换编码资源(通常是时间,有时还包括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.5GB RAM进行解码的文件。

评论


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

–约书亚
2014年12月3日,下午2:23

@Joshua:使用更高密度的物理存储格式与数据压缩不同...

– SamB
2014年12月19日在21:09

#7 楼

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

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

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