Python:如何从内存中的 zip 文件读取图像?

alf*_*dox 6 python io buffer zipfile python-imaging-library

我已经看到了这个问题的变体,但不是在这个确切的上下文中。我有一个名为 100-Test.zip 的文件,其中包含 100 张 .jpg 图像。我想在内存中打开这个文件并处理每个执行 PIL 操作的文件。剩下的代码已经写好了,我只想专注于从 zip 文件到第一个 PIL 图像。这就是我从阅读其他问题中收集到的建议中的代码现在的样子,但它不起作用。大家可以帮忙看看吗?

import zipfile
from StringIO import StringIO
from PIL import Image

imgzip = open('100-Test.zip', 'rb')
z = zipfile.ZipFile(imgzip)
data = z.read(z.namelist()[0])
dataEnc = StringIO(data)
img = Image.open(dataEnc)

print img
Run Code Online (Sandbox Code Playgroud)

但是当我运行它时出现此错误:

 IOError: cannot identify image file <StringIO.StringIO instance at
 0x7f606ecffab8>
Run Code Online (Sandbox Code Playgroud)

替代方案:我看到其他消息来源说要使用它:

image_file = StringIO(open("test.jpg",'rb').read())
im = Image.open(image_file)
Run Code Online (Sandbox Code Playgroud)

但问题是我没有打开文件,它已经在内存中的 data 变量中。我也尝试使用dataEnc = StringIO.read(data)但出现此错误:

TypeError: unbound method read() must be called with StringIO instance as 
first argument (got str instance instead)
Run Code Online (Sandbox Code Playgroud)

Mas*_*edi 10

不需要使用StringIO。zipfile可以读取内存中的图像文件。以下循环遍历 .zip 文件中的所有图像:

import zipfile
from PIL import Image

imgzip = zipfile.ZipFile("100-Test.zip")
inflist = imgzip.infolist()

for f in inflist:
    ifile = imgzip.open(f)
    img = Image.open(ifile)
    print(img)
    # display(img)
Run Code Online (Sandbox Code Playgroud)

  • 我刚刚在一个大型压缩 TIFF 文件(1024*768*116)上尝试了这个想法。虽然它可能适合小文件,但对于大文件来说太慢了。(&gt;20 分钟 vs 未压缩的 6 秒)不过是个好主意...... (2认同)

alf*_*dox 5

原来问题是在 namelist() 中有一个额外的空元素,因为图像被压缩在 zip 文件中的目录中。这是将检查并遍历 100 张图像的完整代码。

import zipfile
from StringIO import StringIO
from PIL import Image
import imghdr

imgzip = open('100-Test.zip')
zippedImgs = zipfile.ZipFile(imgzip)

for i in xrange(len(zippedImgs.namelist())):
    print "iter", i, " ",
    file_in_zip = zippedImgs.namelist()[i]
    if (".jpg" in file_in_zip or ".JPG" in file_in_zip):
        print "Found image: ", file_in_zip, " -- ",
        data = zippedImgs.read(file_in_zip)
        dataEnc = StringIO(data)
        img = Image.open(dataEnc)
        print img
    else:
        print ""
Run Code Online (Sandbox Code Playgroud)

谢谢你们!