Skip to main content
 首页 » 编程设计

python之Pillow 如何直接从 StringIO 打开上传的图像文件

2025年05月04日24grandyang

用户通过 Form 上传图片文件,我不想将原始上传的图片文件保存到磁盘,并通过 Pillow 从磁盘打开图像来调整图像大小。

我想先在内存中调整这个图像文件的大小,然后将调整后的图像文件保存到磁盘。所以我将 StringIO 导入为缓冲区,但它不适用于 Pillow。

代码如下:

Python3.4, Flask==0.10.1, Pillow==3.4.2

表格.py

class Form(): 
    img = FileField() 
    submit = SubmitField() 

View .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

请您参考如下方法:

来自 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.

您传递给 open 的是一个 StringIO。它从以 text 模式打开的 str 对象创建一个类文件对象。
该问题是由 StringIO 中的参数引起的。 form.img.data.read() 返回一个 bytes 对象,禁止将其传递给构造函数。但在您的情况下,StringIO 将不起作用。
相反,请使用 io.BytesIO。它具有几乎相同的界面,除了它采用 bytes 对象并返回以 binary 模式打开的类似文件的对象,这正是您所需要的。

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