【问题标题】:Custom Image Format: How to Target Compression Algorithms自定义图像格式:如何定位压缩算法
【发布时间】:2012-02-24 19:32:52
【问题描述】:

在过去的几天里,我对 PNG 做了一些摆弄,我对自己的发现感到不安。我的结论是,我的大部分结果都与压缩有关。所以这个周末我将深入研究高级压缩文章。到目前为止,我想分享我的发现。看看是否有人对实现我的目标有任何建议,并可能为我指明正确的方向。

我目前正在做一个项目,我需要在不到 15 秒的窗口内获得尽可能小的文件大小。

我使用的大多数图像都是具有完整 256 色调色板的 PNG-8bpp。我可以用 5bpp(32 色)准确地表示这些图像中的大多数。

PNG 索引但仅支持 1、2、4 和 8bpp。所以我的想法是将 PNG 格式剥离为我需要的最少信息,并编写一个编码器/解码器来支持 3、5、6 或 7bpp 的 IDAT 部分。

Test 1:
Original File: 61.5KB, 750 * 500, 8pp Palette, 256 colors, No tRNS
After Optimizations (Reductions to 4bpp, Strip Anx Chunks, & PNGOUT): 49.2KB 4bpp, 16 Colors
Human Interpretation: I can see 6 distinguishable colors.

由于我只需要六种颜色来表示图像,因此我决定使用 3bpp 对 IDAT 进行编码,以提供最多 8 种颜色的调色板。首先,我解压缩了 IDAT,得到了 368KB 的新文件大小。在对 IDAT 应用 3bpp 后,我新的未压缩文件大小为 274KB。我的开始似乎是一个好的开始……接下来我将 deflate 应用到我的新 IDAT 部分。结果... 59KB。

比使用 4bpp 大 10KB。

Test 2:
Original File: 102KB, 1000 * 750, 8bpp, 256 Colors, tRNS 1 fully transparent color
After Optimization: 79KB, 8bpp, 193 colors, tRNS 1 full transparent color
Human Interpretation: I need about 24 colors to represent this picture.

24 种颜色可以以 5bpp 的 32 种颜色表示。使用上述相同的技术,我能够获得比未压缩更好的结果,但我再次在压缩时失败了。最终大小压缩... 84KB。然后我尝试了 6,7bpp...同样的结果,压缩比 8bpp 更差。

只是为了确保我保存了所有未压缩的图像并尝试了其他几种压缩算法...LZMA、BZIP2、PAQ8...相同的结果是 8bpp 的压缩大小比 5,6 或 7bpp 的压缩大小更小,4bpp 的大小更小比 3bpp。

为什么会这样?我可以调整/修改压缩算法以针对使用 5,6 或 7bpp 格式的类似 PNG 的格式来进行 8bpp 压缩吗?值得花时间吗?是的,再节省 10KB 是值得的。

【问题讨论】:

    标签: image compression png deflate quantization


    【解决方案1】:

    您看到的是,通过使用奇数像素大小,您的有效压缩率会因 PNG 压缩的工作方式而降低。与直接使用 FLATE/ZIP 压缩相比,PNG 压缩的优势在于过滤。 PNG 压缩试图利用少量预处理过滤器来利用水平和垂直对称性。这些过滤器在字节边界上工作,并且对 4/8/16/24/32/48/64 位的像素大小有效。当您移动到一个奇数大小的像素(3/5/6/7 位)时,您正在击败过滤,因为在 8 位边界上过滤时,相同颜色的像素不会水平“相互抵消”。

    即使过滤不是问题,FLATE 压缩的工作方式,将像素大小从 8 位减少到 7 或 6 位也不会产生太大影响,因为它还假设符号大小为 8 位。

    总之...使用奇数大小的像素可以获得的唯一好处是未压缩的数据会更小。通过破坏像素的字节边界对称性,您会破坏 PNG 压缩的大部分优势。

    GIF 压缩支持从 1 到 8 位的所有像素大小。它将符号大小定义为像素大小,并且不使用任何预过滤。如果将 8 位 GIF 图像压缩为 7 位像素,则不会受到更少的压缩,但也不会受益,因为压缩更多地取决于像素的重复而不是符号大小。

    【讨论】:

    • 过滤字节在每条扫描线之前总是为零。从我读过的内容来看,过滤通常对索引图像没有好处。因此,我还剥离了过滤器字节以节省空间。我也不必使用 deflate 来压缩 IDAT 部分...我仍在测试其他压缩算法设置,看看是否可以针对更少的 bpp。
    • 过滤可以有利于索引图像;这取决于图像。正如我上面所说,您正在损害 PNG 过滤和寻找重复字节(而不是像素)的 FLATE 压缩的好处。如果您有连续色调(照片类型)图像,那么您不会获得比 JPEG 更好的压缩效果。对于卡通或线条图,LZW (GIF) 对于奇数像素尺寸可能会更好。
    • 在我进行的任何测试中,GIF 文件大小都比具有相同缩减调色板的 PNG8 小 5-7bpp。我能够使用 6bpp 实现更好的压缩,并用比初始 PNG8 的模式填充最后两位。我想知道是否有一种方法可以设置压缩器以每 x 个字节查找模式?因此,对于 6bpp,我希望每 3 个字节作为一个模式。我将尝试使用 LZMA 和 lc lp p 开关。
    • FLATE (PNG) 压缩是对 LZW (GIF) 的改进,如果您坚持使用正确的符号大小。填充到 8bpp 会更好地工作是有道理的。我的观点是关于使用奇数 (3/5/6/7) 尺寸。
    【解决方案2】:

    PNG 使用的 DEFLATE 压缩有两种主要技术:

    • 找到重复的字节序列并将它们编码为反向引用
    • 使用霍夫曼编码对字节进行编码

    通过将像素长度从 8 位更改为与字节边界不同步,DEFLATE 将无法将重复的像素运行编码为重复字节。

    并且由于霍夫曼编码,8 位像素有未使用的位并不重要,因为编码将使用可变宽度代码对字节进行编码,将最短的代码分配给最频繁出现的值。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-02-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多