Mark
Mark

Reputation: 2135

Convert pyBarcode output to PIL Image file

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

Answers (2)

Kade
Kade

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

Martijn Pieters
Martijn Pieters

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

Related Questions