Reputation: 2135
I am trying to convert the output of pyBarcode to a PIL Image file without first saving an image. First off, pyBarcode generates an image file like such:
>>> import barcode
>>> from barcode.writer import ImageWriter
>>> ean = barcode.get_barcode('ean', '123456789102', writer=ImageWriter())
>>> filename = ean.save('ean13')
>>> filename
u'ean13.png'
As you can see above, I don't want the image to be actually saved on my filesystem because I want the output to be processed into a PIL Image. So I did some modifications:
i = StringIO()
ean = barcode.get_barcode('ean', '123456789102', writer=ImageWriter())
ean.write(i)
Now I have a StringIO file object and I want to PIL to "read" it and convert it to a PIL Image file. I wanted to use Image.new
or Image.frombuffer
but both these functions required me to enter a size...can't the size be determined from the barcode StringIO data? Image.open
states this in their documentation:
You can use either a string (representing the filename) or a file object. In the latter case, the file object must implement read, seek and tell methods, and be opened in binary mode
Isn't a StringIO instance a file object as well? How do I open it as a binary file?
Image.open(i, 'rb')
>>> Image.open(i, 'rb')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/mark/.virtualenvs/barcode/local/lib/python2.7/site-packages/PIL/Image.py", line 1947, in open
raise ValueError("bad mode")
ValueError: bad mode
I'm sure I'm pretty close to the answer I just need someone's guidance. Thanks in advance guys!
Upvotes: 10
Views: 5485
Reputation: 1032
The following worked for me to convert the output to a PIL image file:
import barcode
ean = barcode.get('ean13', '123456789102', writer = barcode.writer.ImageWriter())
image = ean.render()
This way does not require StringIO
Upvotes: 8
Reputation: 1124758
StringIO
objects are file objects.
However, if you are using the cStringIO
module (the C-optimized version of the StringIO
module) then do note that once you ceate an emptyStringIO
instance, it is optimized for writing only, and you cannot use it as in input file, and vice-versa. Simply reinitialize it in that case:
i = StringIO(i.getvalue()) # create a cStringIO.StringO instance for a cStringIO.StringI instance.
For the python version (the StringIO
module), simply seek to the start again:
i.seek(0)
You do not need to specify a file mode for the Image.open()
call; unless i
is a string it'll be ignored in any case:
img = Image.open(i)
Upvotes: 7