【问题标题】:PIL "IOError: image file truncated" with big images带有大图像的 PIL“IOError:图像文件被截断”
【发布时间】:2012-10-10 16:03:00
【问题描述】:

我认为这个问题与 Zope 无关。尽管如此,我会解释我正在尝试做的事情:

我在 Zope 中使用 PUT_factory 通过 FTP 将图像上传到 ZODB。上传的图像在新创建的容器对象中保存为 Zope 图像。这很好用,但是如果图像超过一定大小(宽度和高度),我想调整它的大小。所以我使用 PIL 的缩略图功能来调整它们的大小,即 200x200。只要上传的图像相对较小,它就可以正常工作。我没有检查确切的限制,但 976x1296px 还是可以的。

我得到更大的图片:

Module PIL.Image, line 1559, in thumbnail
Module PIL.ImageFile, line 201, in load
IOError: image file is truncated (nn bytes not processed).

我用我的相机测试了很多 jpeg。我不认为它们都被截断了。

这是我的代码:

if img and img.meta_type == 'Image':
  pilImg = PIL.Image.open( StringIO(str(img.data)) )
elif imgData:
  pilImg = PIL.Image.open( StringIO(imgData) )

pilImg.thumbnail((width, height), PIL.Image.ANTIALIAS)

由于我使用的是 PUT_factory,我没有文件对象,我使用的是来自工厂的原始数据或以前创建的 (Zope) Image 对象。

我听说当超过一定大小时 PIL 会以不同的方式处理图像数据,但我不知道如何调整我的代码。还是和PIL的延迟加载有关?

【问题讨论】:

    标签: python image python-imaging-library zope


    【解决方案1】:

    我在这里回复有点晚了,但我遇到了类似的问题,我想分享我的解决方案。首先,这是这个问题的一个非常典型的堆栈跟踪:

    Traceback (most recent call last):
      ...
      File ..., line 2064, in ...
        im.thumbnail(DEFAULT_THUMBNAIL_SIZE, Image.ANTIALIAS)
      File "/Library/Python/2.7/site-packages/PIL/Image.py", line 1572, in thumbnail
        self.load()
      File "/Library/Python/2.7/site-packages/PIL/ImageFile.py", line 220, in load
        raise IOError("image file is truncated (%d bytes not processed)" % len(b))
    IOError: image file is truncated (57 bytes not processed)
    

    如果我们查看第 220 行(在您的情况下为第 201 行——也许您正在运行一个稍微不同的版本),我们看到 PIL 正在读取文件的块,并且它预计这些块将是一定大小。事实证明,您可以通过更改设置来要求 PIL 容忍被截断的文件(从块中丢失一些文件)。

    在代码块之前的某处,只需添加以下内容:

    from PIL import ImageFile
    ImageFile.LOAD_TRUNCATED_IMAGES = True
    

    ...你应该很好。

    编辑:看起来这有助于 PIL 与 Pillow 捆绑的版本(“pip install枕头”),但可能不适用于 PIL 的默认安装

    【讨论】:

    • 只是出于好奇,这会以某种方式影响解析的图像吗? PIL 会对截断的图像保持沉默,但图像会好吗?我想解决我的问题,但我不想得到损坏的图像。
    • Pawel,图片将完成为全尺寸,灰色。
    • 这可行,但它会在我的图像底部留下一个难看的白条。如何动态裁剪掉这个白条?
    • 当我在 python REPL 中尝试这个时,加载大文件没有问题。但是当我把它放到脚本中时,我需要使用from PIL import ImageFile...。多么奇怪,为什么 REPL 和交互式脚本之间的行为不同?
    • 我有点震惊这个旧的解决方案仍然需要并且在 PIL/Pillow 中默认不考虑。无论如何,谢谢你!很多人为此竖起大拇指(实际上我不得不使用imageio 来获得导致这篇文章的类似错误,因为Pillow 只是报告了JpegImageFilefloat 之间的无效操作)。
    【解决方案2】:

    最好的事情是你可以:

    if img and img.meta_type == 'Image':
        pilImg = PIL.Image.open( StringIO(str(img.data)) )
    elif imgData:
        pilImg = PIL.Image.open( StringIO(imgData) )
    
    try:
        pilImg.load()
    except IOError:
        pass # You can always log it to logger
    
    pilImg.thumbnail((width, height), PIL.Image.ANTIALIAS)
    

    尽管看起来很愚蠢 - 它会像奇迹一样工作。如果您的图片缺少数据,则会用灰色填充(检查图片底部)。

    注意:不鼓励在 Python 中使用驼峰式大小写,仅在类名中使用。

    【讨论】:

    • 我无法验证它是否有效,问题奇迹般地消失了。但无论如何谢谢:) 我在这里使用了混合大小写(类名大写),但这也不是真的鼓励......
    【解决方案3】:

    这是我所做的:

    • LOAD_TRUNCATED_IMAGES = False 行从/usr/lib/python3/dist-packages/PIL/ImageFile.py:40 编辑为LOAD_TRUNCATED_IMAGES = True

    但编辑文件需要 root 访问权限。 我在运行一些可能使用 PIL 库的 pytorch 时遇到了这个错误。

    仅在遇到此错误时才进行此修复,而不直接使用 PIL。

    否则请做

    from PIL import ImageFile
    ImageFile.LOAD_TRUNCATED_IMAGES = True
    

    【讨论】:

      【解决方案4】:

      这可能不是 PIL 问题。它可能与您的 HTTP 服务器设置有关。 HTTP 服务器对将被接受的实体主体的大小进行了限制。

      例如,在 Apache FCGI 中,选项 FcgidMaxRequestLen 确定可以上传的文件的最大大小。

      检查您的服务器 - 它可能是限制上传大小的服务器。

      【讨论】:

      • 好点,但这绝对不是 HTTP 问题。在我的条件的第一部分,我访问了 Zope 对象的数据。不涉及 HTTP 请求,数据正常。
      • Feroze 是对的——它是由数据流链中某个点的数据修剪引起的。一个常见的原因是当管道(通过外壳中的“|”)一个命令的输出到另一个命令的输入时,没有刷新输出。它似乎可以工作(没有直接错误),但会产生修剪后的数据。如果您平均修剪了 255 个字节(预计会遇到 \n),那么很可能是原因所在。它也可能有不同的平均值,具体取决于文件类型和内容的字节规律(=无论如何都要检查;])。
      【解决方案5】:

      我也遇到了同样的问题。但是,设置ImageFile.LOAD_TRUNCATED_IMAGES = True 不适用于我的情况,并且我检查了我所有的图像文件都没有损坏,但是很大。

      我使用cv2读取图像,然后将其转换为PIL.Image以解决问题。

      img = cv2.imread(imgfile, cv2.IMREAD_GRAYSCALE)
      img = Image.fromarray(img)
      

      【讨论】:

        【解决方案6】:

        我不得不将 tds 版本更改为 7.2 以防止这种情况发生。也适用于 tds 8.0 版,但是我在 8.0 版中遇到了一些其他问题。

        【讨论】:

          猜你喜欢
          • 2017-11-05
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-12-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-05-29
          相关资源
          最近更新 更多