2012-12-19 67 views
7

我試圖將pyBarcode的輸出轉換爲PIL圖像文件,而無需先保存圖像。首先,pyBarcode產生像這樣的圖像文件:將pyBarcode輸出轉換爲PIL圖像文件

>>> 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美國這個其文檔中:

您可以使用一個字符串(代表文件名)或文件對象。在後一種情況下,文件對象必須實現讀,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 

我確定我很接近答案我只需要別人的指導。在此先感謝你們!

+1

您是否嘗試過省略掉'Image.open'(我的意思,只是在默認模式下打開它)的第二個參數? –

+1

您是否'.seek(0)'返回到'StringIO'的開頭?然後,如PauloScardine所建議的,省略第二個參數。可能也想嘗試使用'io.BytesIO'。 –

+0

謝謝你們!尋找(0)並省略第二個參數的伎倆! – Mark

回答

7

StringIO對象文件對象。

但是,如果您使用的是cStringIO module(該StringIO模塊的C-優化版本),那麼請注意,一旦你ceate空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) 
+0

非常感謝! i.seek(0)做到了。雖然我不明白你的意思,重新初始化StringIO(i.getvalue()) – Mark

+0

@Mark:'從cStringIO import StringIO',然後'StringIO('somevalue')'創建一個輸出(只讀)對象,而'StringIO()'創建一個輸入對象(只寫)。所以要從寫作轉向閱讀,你必須從後者創建第一種類型。 –

+0

啊!我知道了。你的意思是,如果我提供了一個參數,輸出將是隻讀的,就好像我省略了參數一樣,輸出將是隻寫的。你是這個意思嗎? – Mark