2016-12-27 96 views
0

用戶通過表單上傳圖像文件,我不想將原始上傳的圖像文件保存到磁盤,並通過Pillow從磁盤打開圖像來調整圖像大小。Pillow如何直接從StringIO打開上傳的圖像文件?

我想先在內存中調整此圖像文件的大小,然後將調整大小的圖像文件保存到磁盤。所以我將StringIO作爲緩衝區導入,但它不適用於Pillow。

下面是代碼:

Python3.4,瓶== 0.10.1,枕頭== 3.4.2

forms.py
class Form(): 
    img = FileField() 
    submit = SubmitField() 

views.py
from io import StringIO 
from PIL import Image 
from .forms import Form 

@app.route('/upload_img', methods=['GET', 'POST']) 
def upload_img(): 
    form = Form() 
    im = Image.open(StringIO(form.img.data.read()) 

    pass 

TypeError: initial_value must be str or None, not bytes

回答

2

Pillow docs

PIL.Image.open(fp, mode='r')

Opens and identifies the given image file. Parameters:

fp – A filename (string), pathlib.Path object or a file object. The file object must implement read() , seek() , and tell() methods, and be opened in binary mode.

什麼你傳遞給openStringIO。它從文本模式中打開的str對象中創建一個類似文件的對象。
該問題是由StringIO中的參數引起的。 form.img.data.read()返回一個bytes對象,將其傳遞給構造函數是禁止的。但在你的情況下,StringIO將無法​​正常工作。
而是使用io.BytesIO。它有幾乎相同的界面,除了它需要bytes對象並返回一個類似文件的對象,以二進制模式打開,這就是你所需要的。

from io import BytesIO 
from PIL import Image 
from .forms import Form 

@app.route('/upload_img', methods=['GET', 'POST']) 
def upload_img(): 
    form = Form() 
    im = Image.open(BytesIO(form.img.data.read()) 

    pass 
+0

是,I'vd試圖與BytesIO,但仍與OSERROR:不能識別的圖像文件<_io.BytesIO對象在0x03B07880> – rogwan

+0

@rogwan然後從'form.img.data.read返回的數據() '不是一個有效的圖像。您可以通過以二進制模式打開文件並在其中寫入返回值來測試該文件。如果圖像被損壞,那麼你將不得不調查爲什麼圖像數據不能正確傳輸 – Leva7

+0

好的,感謝您的建議,直接打開文件存儲將是理想的解決方案。 – rogwan