我正在尝试使用 python (vscode) 上的 zlib 库压缩图像。我生成了一个输出文件,但它的权重与原始文件相同。
这是代码:
import zlib
with open("garenap.jpg", "rb") as in_file:
compressed = zlib.compress(in_file.read(), -1)
with open("arroz", "wb") as out_file:
out_file.write(compressed)
我正在尝试使用 python (vscode) 上的 zlib 库压缩图像。我生成了一个输出文件,但它的权重与原始文件相同。
这是代码:
import zlib
with open("garenap.jpg", "rb") as in_file:
compressed = zlib.compress(in_file.read(), -1)
with open("arroz", "wb") as out_file:
out_file.write(compressed)
我认为这两个文件的重量不会完全相同。如果您尝试以下操作:
import zlib
with open("garenap.jpg", "rb") as in_file:
compressed = zlib.compress(in_file.read(), -1)
print(in_file.tell())
with open("arroz", "wb") as out_file:
out_file.write(compressed)
print(out_file.tell())
您应该看到两个略有不同的数字(基本上是文件大小)。
对于我的一些jpg人,我得到了:
3563384
3448655
所以这zlib.compress()实际上是在减少文件大小。你自己也应该观察类似的东西。任何不同的数字都可以。
正如@jasonharper 已经指出的那样,JPEG格式已经被高度压缩,但没有像DEFLATE那样压缩zlib(包括Python 中可用的实现)。这与 JPEG 中实现的有损压缩有点不同,后者基于积分变换。此转换的输出通常是非冗余的,因此使用 DEFLATE(或任何其他实现,值得一提)实现的Lempel-Ziv 77 算法的功效有限。
总之,zlib正在做它的工作,但它不太可能对jpeg数据有效。
zlib压缩文件可以大于它们的输入。
这对于任何无损压缩算法都是如此,并且可以很容易地证明:考虑一个无损算法的多个连续应用,如果任何应用会严格减小文件大小,你最终会得到一个等于 的大小0,即一个空文件。显然,这不能颠倒过来,从而证明无损压缩与始终减小文件大小不兼容。
从维基百科查看 LZ77 的详细信息:
LZ77 算法通过将重复出现的数据替换为对未压缩数据流中较早存在的数据的单个副本的引用来实现压缩。
以下内容并不完全是 LZ77 的工作原理,但应该会给您一些想法。让我们将重复字符替换为字符后跟重复次数。该算法xxxxxxxx在减少到x8(x8 次)时效果很好。如果序列是非冗余的,例如abcdefgh,那么这个算法将产生a1b1c1d1e1f1g1h1不会减少输入大小,但实际上会加倍它。你正在观察的是类似的东西。