Convert PILLOW image into StringIO

折月煮酒 提交于 2019-12-09 05:39:41

问题


I'm writing a program which can receive images in a variety of common image formats but needs to examine them all in one consistent format. It doesn't really matter what image format, mainly just that all of them are the same. Since I need to convert the image format and then continue working with the image, I don't want to save it to disk; just convert it and continue on. Here's my attempt using StringIO:

image = Image.open(cStringIO.StringIO(raw_image)).convert("RGB")
cimage = cStringIO.StringIO() # create a StringIO buffer to receive the converted image
image.save(cimage, format="BMP") # reformat the image into the cimage buffer
cimage = Image.open(cimage)

It returns the following error:

Traceback (most recent call last):
  File "server.py", line 77, in <module>
    s.listen_forever()
  File "server.py", line 47, in listen_forever
    asdf = self.matcher.get_asdf(data)
  File "/Users/jedestep/dev/hitch-py/hitchhiker/matcher.py", line 26, in get_asdf
    cimage = Image.open(cimage)
  File "/Library/Python/2.7/site-packages/PIL/Image.py", line 2256, in open
    % (filename if filename else fp))
IOError: cannot identify image file <cStringIO.StringO object at 0x10261d810>

I've also tried with io.BytesIO with the same results. Any suggestions as to how to approach this?


回答1:


There are two types of cStringIO.StringIO() objects depending on how the instance was created; one for just reading, the other for writing. You cannot interchange these.

When you create an empty cStringIO.StringIO() object, you really get a cStringIO.StringO (note the O at the end) class, it can only act as output, i.e. write to.

Conversely, creating one with initial content produces a cStringIO.StringI object (ending in I for input), you can never write to it, only read from it.

This is particular to just the cStringIO module; the StringIO (pure python module) does not have this limitation. The documentation uses the aliases cStringIO.InputType and cStringIO.OutputType for these, and has this to say:

Another difference from the StringIO module is that calling StringIO() with a string parameter creates a read-only object. Unlike an object created without a string parameter, it does not have write methods. These objects are not generally visible. They turn up in tracebacks as StringI and StringO.

Use cStringIO.StringO.getvalue() to get the data out of an output file:

# replace cStringIO.StringO (output) with cStringIO.StringI (input)
cimage = cStringIO.StringIO(cimage.getvalue())
cimage = Image.open(cimage)

You can use io.BytesIO() instead, but then you need to rewind after writing:

image = Image.open(io.BytesIO(raw_image)).convert("RGB")
cimage = io.BytesIO()
image.save(cimage, format="BMP")
cimage.seek(0)  # rewind to the start
cimage = Image.open(cimage)


来源:https://stackoverflow.com/questions/24920728/convert-pillow-image-into-stringio

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!