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

rog*_*wan 1 python stringio flask pillow

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

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

这是代码:

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

forms.py

class Form():
    img = FileField()
    submit = SubmitField()
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

TypeError:initial_value必须是str或None,而不是字节

ill*_*ght 5

来自枕头文档:

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

打开并标识给定的图像文件.参数:

fp- 文件名(字符串),pathlib.Path对象或文件对象.文件对象必须实现read(),seek()tell()方法,并以二进制模式打开.

你传递给的open是一个StringIO.它从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
Run Code Online (Sandbox Code Playgroud)