【问题标题】:How to read an image inside a zip file with PIL/Pillow如何使用 PIL/Pillow 读取 zip 文件中的图像
【发布时间】:2015-10-16 08:57:50
【问题描述】:

我可以使用 PIL/Pillow 打开 zip 内的图像而不先将其解压缩到磁盘吗?

【问题讨论】:

    标签: python python-imaging-library zipfile pillow


    【解决方案1】:

    最近的 Pillow 版本不需要.seek()

    #!/usr/bin/env python
    import sys
    from zipfile import ZipFile
    from PIL import Image # $ pip install pillow
    
    filename = sys.argv[1]
    with ZipFile(filename) as archive:
        for entry in archive.infolist():
            with archive.open(entry) as file:
                img = Image.open(file)
                print(img.size, img.mode, len(img.getdata()))
    

    【讨论】:

    • 谢谢,你知道Pillow是从哪个版本开始的吗?
    • @TorKlingberg:它在 2.7 上失败了。它适用于 2.9+。您可以尝试在 github 上查找特定问题。
    • Image.open 的当前documentation 仍然显示“文件对象必须实现 read()、seek() 和 tell() 方法”
    • @TorKlingberg:“必须”可能是文档中的一个错误。这是release notes for 2.8 that explicitly says that Image wraps the non-seekable files itself
    • 那很好。 Ubuntu 14.04 只有 Pillow 2.3.0。我会考虑设置一个 virtualenv。
    【解决方案2】:

    Pythons zipfile 确实提供了一个 ZipFile.open(),它为 zip 中的文件返回一个文件对象,PillowImage.open() 可以使用文件对象打开。不幸的是,zipfile 对象没有提供Image.open() 需要的seek() 方法。

    而是将图像文件读入RAM中的字符串(如果不是太大),并使用StringIO获取Image.open()的文件对象:

    from zipfile import ZipFile
    from PIL import Image
    from StringIO import StringIO
    
    archive = ZipFile("file.zip", 'r')
    image_data = archive.read("image.png")
    fh = StringIO(image_data)
    img = Image.open(fh)
    

    【讨论】:

    • 使用io.BytesIO而不是StringIO可能会更好,尽管在这种情况下两者似乎都有效。
    • StringIO 在我的机器上不起作用...“TypeError: initial_value must be str or None, not bytes”, no pb using BytesIO
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-08-05
    • 1970-01-01
    • 1970-01-01
    • 2012-05-25
    • 2017-10-17
    • 1970-01-01
    • 2021-03-04
    相关资源
    最近更新 更多