您的实际问题很可能不在于 PIL,而在于您用于显示图像的任何内容。
您的问题也可能与 PIL 有关,并且已由 Pillow 2.0 修复,或者它仅发生在 32 位或其他任何情况下,但我无法重现它。
无论如何,这是我从一堆 512x60 PNG 副本中生成 2Mx60 PNG 文件的代码,该文件未压缩超过 300MB(但压缩后小于 1MB):
>>> src = PIL.Image.open('strip-512x60.png')
>>> dst = PIL.Image.new('RGBA', (4096*512, 60))
>>> for i in range(4096):
... dst.paste(src, (4096*i, 0))
>>> dst.save('strip-3Mx60.png')
我检查了文件;它有一个有效的 PNG 块结构和 IHDR 中的所有正确信息。
我可以在 PIL 中重新打开它,像素显然是有效的:
>>> dst = PIL.Image.open('strip-3Mx60.png')
>>> src.getpixel((0, 30))
(115, 67, 19)
>>> dst.getpixel((0, 30))
(115, 67, 19)
>>> dst.getpixel((4000*512, 30))
(115, 67, 19)
ImageMagick 的命令行工具也可以很好地读取文件;将倒数第二个 512x512 裁剪成一个新文件并打开它给了我原始图像(或者至少足够接近以通过快速目视检查的图像)。
但是,我尝试打开它的几乎所有其他程序或高级库都失败了,或者给了我垃圾:
- QuickLook 系统日志“ImageIO: PNG Invalid IHDR Data”然后返回 0x0 图像。
- 一个简单的 CoreImage 测试程序系统日志“ImageIO: PNG Invalid IHDR Data”然后返回一个纯黑色图像,我猜这是默认大小(大约 600x600)。
- 预览给出关于无效文件类型的错误。
- Firefox 给出关于无效图像内容的错误。
- Chrome 和 Safari 显示损坏的图像标签。这需要几分钟。
- LibreOffice Draw 为我提供了一个类似于 600x64K 的图像,由奇异的红色、白色和黑色带组成。它甚至比 WebKit 需要更长的时间。
- 一个简单的 .NET 图像查看器(在 Mono 中运行)会吐出大量错误,然后显示传统的模拟电视风格的静态图像。它需要的时间甚至比 LibreOffice 还要长。
据推测,Apple 的库(WebKit 除外)和 Gecko 只是在进行某种健全性检查,并决定任何声称为 2M 像素宽的 IHDR 都是无效的,而其他一切都试图解释图像,然后在任何一个之前溢出一些内部缓冲区中止,或没有注意到,只是返回垃圾。