据说PNG文件使用无损压缩。但是,每当我使用图像编辑器(例如GIMP)并尝试将图像另存为PNG文件时,它都会要求压缩参数,其范围在0到9之间。如果它的压缩参数会影响图像的视觉精度,压缩的图像,它如何使PNG无损?
仅当将压缩参数设置为9时,我才能获得无损行为吗?
据说PNG文件使用无损压缩。但是,每当我使用图像编辑器(例如GIMP)并尝试将图像另存为PNG文件时,它都会要求压缩参数,其范围在0到9之间。如果它的压缩参数会影响图像的视觉精度,压缩的图像,它如何使PNG无损?
仅当将压缩参数设置为9时,我才能获得无损行为吗?
Answers:
PNG是无损的。在这种情况下,GIMP很可能只是不使用最佳单词。可以将其视为“压缩质量”,换句话说,就是“压缩级别”。使用较低的压缩率,您可以获得较大的文件,但生成时间较短,而使用较高的压缩率,则文件较小,而生成时间更长。通常,在达到最高压缩级别时,收益会递减(即,与所需的时间增加相比,大小的减少不会那么大),但这取决于您。
pngcrush
可以比较许多变化以达到最小的可能。
压缩级别是文件大小和编码/解码速度之间的权衡。为了过度概括,甚至非图像格式(例如FLAC)也具有类似的概念。
尽管文件大小不同,但由于压缩级别不同,实际的解码输出将相同。
您可以使用MD5多路复用器比较解码输出的MD5哈希值。ffmpeg
最好通过一些示例显示:
$ 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
$ ffmpeg -loglevel error -i 0.png -f md5 -
3d3fbccf770a51f9d81725d4e0539f83
$ ffmpeg -loglevel error -i 100.png -f md5 -
3d3fbccf770a51f9d81725d4e0539f83
由于两个哈希值相同,因此可以确保解码后的输出(未压缩的原始视频)完全相同。
ffmpeg -ss 30 -i input -vframes 1 output.png
同样适用于用图像制作视频,反之亦然。
PNG压缩分为两个阶段。
由于步骤2是一项非常耗时/耗费资源的任务,因此底层zlib库(原始DEFLATE的封装)采用的压缩参数范围为1 =最快压缩,9 =最佳压缩,0 =无压缩。这就是0-9范围的来源,GIMP只是将该参数向下传递给zlib。请注意,在0级时,您的png实际上会比等效的位图稍大。
但是,级别9只是zlib将尝试的“最佳”,仍然是一个非常妥协的解决方案。
为了真正体会到这一点,如果您愿意在详尽的搜索上花费1000倍的处理能力,则可以使用zopfli而不是zlib来将数据密度提高3-8%。
压缩仍然是无损的,只是数据的最佳DEFLATE表示。这接近与zlib兼容的库的限制,因此是使用PNG可以实现的真正的“最佳”压缩。
PNG格式的主要动机是创建GIF的替代品,该替代品不仅免费,而且在各个方面都对其进行了改进。结果,PNG压缩是完全无损的-也就是说,可以像GIF和大多数形式的TIFF一样,一点一点地精确地重建原始图像数据。
PNG使用两阶段压缩过程:
预压缩步骤称为过滤,这是一种可逆地转换图像数据的方法,以便主压缩引擎可以更高效地运行。
举一个简单的例子,考虑字节序列从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具有一个压缩参数,可以极大地减小文件大小,而所有这些都不会损失单个像素。
资料来源:
好的,我来不及获得赏金,但是无论如何这是我的答案。
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。
无损内容中的压缩级别始终只是交换编码资源(通常是时间,有时还包括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的文件。
首先,PNG始终是无损的。明显的悖论是由于存在两种可能的压缩方式(对于任何类型的数据):有损和无损。
无损压缩使用各种技巧来压缩数据(即文件大小),从而保留所有内容且不做任何近似。结果,无损压缩实际上可能根本无法压缩所有内容。(从技术上讲,对于无损方法,具有高熵的数据可能很难压缩,甚至无法压缩。) 有损压缩近似于实际数据,但是近似并不完美,但是这种“丢弃”的精度通常可以实现更好的压缩。
这是一个无损压缩的简单示例:如果您的图像由1,000个黑色像素组成,则可以存储一个计数(1000)和一个值(黑色),而不是存储1000次黑色值,从而压缩1000个像素,图片”分成两个数字。(这是一种称为游程长度编码的无损压缩方法的粗略形式)。