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

时间:2015-08-02 22:15:55

标签: python io buffer python-imaging-library zipfile

我看过这个问题的变体,但不是在这个确切的背景下。我所拥有的是一个名为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

但是当我运行它时,我收到了这个错误:

 IOError: cannot identify image file <StringIO.StringIO instance at
 0x7f606ecffab8>

替代方案:我见过其他消息来源说使用它:

image_file = StringIO(open("test.jpg",'rb').read())
im = Image.open(image_file)

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

TypeError: unbound method read() must be called with StringIO instance as 
first argument (got str instance instead)

4 个答案:

答案 0 :(得分:3)

原来问题是,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 ""

谢谢你们!

答案 1 :(得分:1)

如果需要处理像素数据,则可以按照以下步骤从zip文件中以numpy数组的形式加载图像流数据,并保持原始数据形状(即32x32 RGB):

  1. 使用zipfile获取ZipExtFile格式
  2. 使用PIL.Image将ZipExtFile转换为类似于数据结构的图像
  3. 将PIL.image转换为numpy数组

无需重塑具有原始数据形状的numpy数组,因为PIL.Image已经具有该信息。因此输出将是一个shape =(32,32,3)的numpy数组

<div class="switch form-switch" role="switch">
  <input type='checkbox' id='switch' [(ngModel)]="isReadonly" [ngModelOptions]="{standalone: true}">
  <label for='title_switch'>Switch</label>
</div>

答案 2 :(得分:0)

我有同样的问题,感谢@alfredox,我修改了答案,在python3中使用io.BytesIO而不是StringIo。

z = zipfile.ZipFile(zip_file)
for i in range(len(z.namelist())):

    file_in_zip = z.namelist()[i]
    if (".jpg" in file_in_zip or ".JPG" in file_in_zip):

        data = z.read(file_in_zip)
        dataEnc = io.BytesIO(data)
        img = Image.open(dataEnc)
        print(img)

答案 3 :(得分:0)

不需要使用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)