【问题标题】:Convert pyBarcode output to PIL Image file将 pyBarcode 输出转换为 PIL 图像文件
【发布时间】:2012-12-19 12:54:42
【问题描述】:

我正在尝试将 pyBarcode 的输出转换为 PIL 图像文件,而无需先保存图像。首先,pyBarcode 会生成一个像这样的图像文件:

>>> import barcode
>>> from barcode.writer import ImageWriter
>>> ean = barcode.get_barcode('ean', '123456789102', writer=ImageWriter())
>>> filename = ean.save('ean13')
>>> filename
u'ean13.png'

正如您在上面看到的,我不希望图像实际保存在我的文件系统上,因为我希望将输出处理成 PIL 图像。所以我做了一些修改:

i = StringIO()
ean = barcode.get_barcode('ean', '123456789102', writer=ImageWriter())
ean.write(i)

现在我有一个 StringIO 文件对象,我想 PIL “读取”它并将其转换为 PIL 图像文件。我想使用Image.newImage.frombuffer 但这两个功能都需要我输入一个尺寸...不能从条形码StringIO 数据中确定尺寸吗? Image.open 在他们的文档中声明了这一点:

您可以使用字符串(表示文件名)或文件对象。在后一种情况下,文件对象必须实现 read、seek 和 tell 方法,并以二进制模式打开

StringIO 实例不也是文件对象吗?如何将其作为二进制文件打开?

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

我确定我非常接近答案,我只需要有人指导。提前谢谢各位!

【问题讨论】:

  • 你有没有试过省略Image.open中的第二个参数(我的意思是,在默认模式下打开)?
  • 你有没有.seek(0)回到StringIO的开头?然后,正如 PauloScardine 建议的那样,省略第二个参数。可能也想尝试使用io.BytesIO
  • 谢谢大家! seek(0) 并省略第二个参数就可以了!

标签: python python-imaging-library


【解决方案1】:

StringIO 对象文件对象。

但是,如果您使用的是 cStringIO moduleStringIO 模块的 C 优化版本),请注意,一旦您创建了一个空的StringIO 实例,它就只针对写入进行了优化,您不能在输入文件中使用它,反之亦然。在这种情况下只需重新初始化它:

i = StringIO(i.getvalue())  # create a cStringIO.StringO instance for a cStringIO.StringI instance.

对于 python 版本(StringIO 模块),只需重新开始:

i.seek(0)

您确实不需要需要为Image.open() 调用指定文件模式;除非i 是字符串,否则无论如何都会被忽略:

img = Image.open(i)

【讨论】:

  • 非常感谢! i.seek(0) 成功了。虽然我不太明白重新初始化 StringIO(i.getvalue()) 是什么意思
  • @Mark: from cStringIO import StringIO,然后StringIO('somevalue') 创建一个输出(只读)对象,而StringIO() 创建一个输入对象(只写)。所以要从写切换到读,你必须从后者创建第一个类型。
  • 啊!!我知道了。您的意思是,如果我提供一个参数,则输出将是只读的,而就好像我要省略参数一样,输出将是只写的。这是你的意思吗?
  • @Mark:没错。这是cStringIO 模块的许多用户遇到的问题。
  • 感谢您提供非常有用的提示!
【解决方案2】:

以下内容对我有用,可以将输出转换为 PIL 图像文件:

import barcode
ean = barcode.get('ean13', '123456789102', writer = barcode.writer.ImageWriter())
image = ean.render()

这种方式不需要StringIO

【讨论】:

  • 不知道为什么这没有被标记为正确答案。它很简单,并提供&lt;class 'PIL.Image.Image'&gt; 图像以根据需要进行编辑。太好了!
  • 更好的解决方案
猜你喜欢
  • 2023-04-07
  • 2015-12-31
  • 1970-01-01
  • 2020-11-22
  • 1970-01-01
  • 2016-05-29
  • 1970-01-01
  • 1970-01-01
  • 2016-12-04
相关资源
最近更新 更多