Frontend=Vue.js、Backend=Flaskで画像投稿。PythonでBinary操作。

前書き

そういえば3ヶ月前にこんな記事をQiitaに投稿しました。
最初の方はいまいち中身を理解してなかったのですが、
インターンでバイナリ操作、
Axiosを触るようになって理解した画像投稿部分を説明します。
記事も更新しました。

qiita.com

Vueの箇所

// アップロードした画像を表示
    createImage (file) {
      let reader = new FileReader()
      reader.onload = (e) => {
        this.uploadedImage = e.target.result
      }
      reader.readAsDataURL(file)
    },

FileReaderでは、ユーザーが読み込んだファイルを非同期で取得、
その後BlobもしくはFileオブジェクトとして取得できます。

developer.mozilla.org

// 画像をサーバーへアップロード
    onUploadImage () {
      var params = new FormData()
      params.append('image', this.uploadedImage)
      // Axiosを用いてFormData化したデータをFlaskへPostしています。
      axios.post(`${API_URL}/classification`, params).then(function (response) {
        console.log(response)
    })

FormDataのドキュメントでは、
生成したオブジェクトにKeyとValueに値を埋め込む事が可能です。
このデータをAxiosでURIを指定して、引数に当てはめる事で送信できます。


developer.mozilla.org

Flaskの箇所

@app.route('/classification', methods=['POST'])
def uploadImage():
    if request.method == 'POST':
        base64_png =  request.form['image']
        code = base64.b64decode(base64_png.split(',')[1]) 
        image_decoded = Image.open(BytesIO(code))
        image_decoded.save(Path(app.config['UPLOAD_FOLDER']) / 'image.png')
        return make_response(jsonify({'result': 'success'}))
    else: 
        return make_response(jsonify({'result': 'invalid method'}), 400)

上記のrequestでは、key:imageに画像データが格納されています。
base64.b64encode()でバイナリデータをエンコードされたByte型で出力。
Base64とは英数字+/で構成された文字列。
バイナリデータをBase64エンコードする事で、
受け取り側での取得データの齟齬を防ぐ安全な通信が可能なそうです。

Pillow(Pythonの画像処理ライブラリ)で何らかのファイルを開こうとしていますが、
このファイルの中身:"code"はバイナリデータとなっています。
BytesIOはメモリ上のバイナリデータをPythonで操作でき、
音声データや動画データでも対応できるので便利そう。

techacademy.jp