1

I have a set of jpeg files in a zip archive. I would like to display a member jpeg image in a Tkinter widget.

I'm having trouble creating an Image object. I have tried feeding the output of ZipFile.open() and ZipFile.read() to Image() and PhotoImage(), all of which result in the same error message: "UnsupportedOperation: seek". Documentation for Image.open() states that if a file object is given as the argument, the file object must support the read, seek, and tell methods. Apparently the "file-like object" returned by ZipFile.open() does not qualify.

zfile = zipfile.ZipFile(filename,'r')
...
filelikeobject = zfile.open(membername,'r')
image = Image.open(filelikeobject)

File "/usr/lib/python2.7/dist-packages/PIL/Image.py", line 1967, in open
fp.seek(0)
UnsupportedOperation: seek

I cannot find any relevant post dealing with zipped jpeg files. I know my zips are well-formed because I can perform this operation, using the same files, in Java and Perl (I am re-writing a large Java application in Python/Tk).

A brute force method would be to extract the member file to disk, and simply call Image(pathname), but I'd rather do everything in memory.

Any help, please.

fossildoc
  • 31
  • 5
  • Can http://stackoverflow.com/questions/12821961/seek-a-file-within-a-zip-file-in-python-without-passing-it-to-memory help you? – Eric Levieil Jun 06 '15 at 15:02
  • Also you should add the python tag to have more readers... – Eric Levieil Jun 06 '15 at 15:04
  • Eric: I've seen that post; it doesn't help, but thank you. I solved my problem by feeding ZipFile.read(membername) to BytesIO, which returns a seekable memory file. Image.open accepts it, and everything after that is easy. I welcome any other solutions. – fossildoc Jun 06 '15 at 20:57
  • If you have found a solution then the best thing to do is to post it as an answer. – Eric Levieil Jun 06 '15 at 22:03

1 Answers1

1

I was able to create a seekable memory file from a (nonseekable) ZipFile object as follows:

from io import BytesIO
import zipfile
from PIL import Image, ImageTk
...
zfile = zipfile.ZipFile(filename,'r')  # non-seekable
memberlist = zfile.namelist()
...
zfiledata = BytesIO(zfile.read(membername)) # seekable
image = Image.open(zfiledata)  # image.show() will display
photo = ImageTk.PhotoImage(image)

Photo can then be used in any Tk widget which takes an image object (e.g., Canvas, Label, etc.)

On my first try of the above code, I got an error message about missing files. Apparently ImageTk is not part of the standard 2.7 installation. Instructions for installing it I found in a SO post.

Community
  • 1
  • 1
fossildoc
  • 31
  • 5