代码之家  ›  专栏  ›  技术社区  ›  Chaban33

Flask表单图像转换为base64字符串

  •  0
  • Chaban33  · 技术社区  · 4 年前

    我创建了一个Flask表单,可以在其中上传图像。然后我需要将该图像转换为base64字符串,但我总是得到相同的结果。 打印输出:

    <FileStorage: '20190925_184412.jpg' ('image/jpeg')>
    b''
    

    以及代码

    from flask import Flask, render_template
    from flask_wtf import FlaskForm
    from wtforms import FileField
    from flask_uploads import configure_uploads, IMAGES, UploadSet
    import base64
    app = Flask(__name__)
    
    app.config['SECRET_KEY'] = 'thisisasecret'
    app.config['UPLOADED_IMAGES_DEST'] = 'uploads/images'
    
    images = UploadSet('images', IMAGES)
    configure_uploads(app, images)
    
    
    class MyForm(FlaskForm):
        image = FileField('image')
    
    
    @app.route('/', methods=['GET', 'POST'])
    def index():
        form = MyForm()
    
        if form.validate_on_submit():
            filename = images.save(form.image.data)
            image_string = base64.b64encode(form.image.data.read())
            print(form.image.data)
            print(image_string)
            return f'Filename: { filename }'
    
        return render_template('index.html', form=form)
    
    0 回复  |  直到 4 年前
        1
  •  1
  •   v25    4 年前

    我认为这是由于Werkzeug的FileStorage对象的工作方式造成的。正如我 menioned in another answer 它有一个 stream 属性;这是类型 tempfile.SpooledTemporaryFile 所以如果你想再读一遍,一定要在读完后重新包扎。

    在您的情况下,此流属性为: form.image.data.stream 。我怀疑当你调用该方法时,它会被读取一次 images.save .

    因此,解决方案应该是在计算b64字符串之前倒带该流:

       if form.validate_on_submit():
            filename = images.save(form.image.data) # first read happens here
    
            form.image.data.stream.seek(0)
    
            image_string = base64.b64encode(form.image.data.read())
            print(form.image.data)
            print(image_string)
            return f'Filename: { filename }'