1

I created a Flask form where I can upload an image. Then I need to convert that image to base64 string, but I'm always getting the same result. OUTPUT of my prints:

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

And the code

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)
Chaban33
  • 1,362
  • 11
  • 38
  • I answered. Haven't used the `Flask-Upload` library myself, so hopefully my code works for your configuration, let me know if not :) – v25 Aug 09 '20 at 19:47

1 Answers1

1

I think this is due to the way Werkzeug's FileStorage object works. As I menioned in another answer it has a stream attribute; this is of type tempfile.SpooledTemporaryFile so must be re-wound after reading, if you wish to read it again.

In your case this stream attribute is: form.image.data.stream. I suspect this is read once when you call the method images.save.

So the solution should be to rewind that stream, prior to calculating the the b64 string:

   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 }'
v25
  • 7,096
  • 2
  • 20
  • 36