【问题标题】:How can Pillow open uploaded image file from StringIO directly?Pillow 如何直接从 StringIO 打开上传的图片文件?
【发布时间】:2017-05-11 10:51:57
【问题描述】:

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

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

代码如下:

Python3.4,Flask==0.10.1,Pillow==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 必须是 str 或 None,而不是 bytes

【问题讨论】:

    标签: python flask pillow stringio


    【解决方案1】:

    来自Pillow docs

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

    打开并识别给定的图像文件。参数:

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

    您传递给open 的是StringIO。它从以 text 模式打开的 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
    

    【讨论】:

    • 是的,我已经尝试过使用 BytesIO,但仍然出现 OSError: cannot identify image file <_io.bytesio object at>
    • @rogwan 那么从form.img.data.read() 返回的数据不是有效的图像。您可以通过简单地以二进制模式打开文件并在其中写入返回值来测试它。如果图像将被损坏,那么您将不得不调查图像数据未正确传输的原因
    • 好的,感谢您的建议,直接打开文件存储将是理想的解决方案。
    猜你喜欢
    • 1970-01-01
    • 2014-09-15
    • 2012-08-14
    • 2017-05-25
    • 2014-04-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多