Vue.js+Flask로 이미지 업로드 기능

개요



이번에는 프런트 엔드에 Vue.js, 백엔드에 Flask를 이용한 이미지 인식 앱을 만듭니다.
일단 이번은 이미지 업로드 기능까지의 구현입니다.

환경


  • Docker
  • Vue-cli
  • flask (pipenv)

  • 위의 환경에서 환경을 구축했습니다.
    자세한 지침과 자세한 내용은 아래 링크를 참조하십시오.

    Vue + Flask on Docker

    요소 설명



    Vue



    자세한 내용은 다음 코드입니다.

    Home.vue
    // 画像をサーバーへアップロード
        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)
        })
    
  • 취득한 화상은 Base64화가 이루어지고 있다. 「data:image/jpeg:base64,~」
  • FormData는 HTTP 요청으로 데이터를 "키 : 값"형식으로 변환합니다.
  • Axios를 적용하고 '127.0.0.1:5000/classification'+ POST 메서드로 데이터를 전송합니다.

  • Flask



    자세한 내용은 다음 코드입니다.

    app.py
    @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)
    
  • FormData의 내부에 「data:image/jpeg:base64,~」가 존재. 파일명을 취득.
  • Pillow (PIL)로 이미지를 가져옵니다.
  • 이미지 저장.

  • 전체상



    Vue



    Home.vue
    <template>
      <div>
        <div class="imgContent">
          <div class="imagePreview">
            <img :src="uploadedImage" style="width:100%;" />
          </div>
          <input type="file" class="file_input" name="photo" @change="onFileChange"  accept="image/*" />
          <button @click='onUploadImage'>画像判定してくだちい・・・</button>
        </div>
      </div>
    </template>
    
    <script>
    import axios from 'axios'
    
    const API_URL = 'http://127.0.0.1:5000'
    export default {
      data () {
        return {
          uploadedImage: ''
        }
      },
      methods: {
        // 選択した画像を反映
        onFileChange (e) {
          let files = e.target.files || e.dataTransfer.files
          this.createImage(files[0])
        },
        // アップロードした画像を表示
        createImage (file) {
          let reader = new FileReader()
          reader.onload = (e) => {
            this.uploadedImage = e.target.result
          }
          reader.readAsDataURL(file)
        },
        // 画像をサーバーへアップロード
        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)
          })
        }
      }
    }
    </script>
    

    Flask



    유의점


  • CORS를 사용하면 다른 출처 (프로토콜, 도메인, 포트)에서 리소스를 공유 할 수 있습니다.
  • CORS가 다른 웹 응용 프로그램을 가지고 있으면 필수입니다.
  • app.config['JSON_AS_ASCII'] = False 에 의해 일본어 대응 가능.

  • app.py
    # render_template:参照するテンプレートを指定
    # jsonify:json出力
    from flask import Flask, render_template, jsonify, request, make_response
    
    # CORS:Ajax通信するためのライブラリ
    from flask_restful import Api, Resource
    from flask_cors import CORS 
    from random import *
    from PIL import Image
    from pathlib import Path
    from io import BytesIO
    import base64
    
    # static_folder:vueでビルドした静的ファイルのパスを指定
    # template_folder:vueでビルドしたindex.htmlのパスを指定
    app = Flask(__name__, static_folder = "./../frontend/dist/static", template_folder="./../frontend/dist")
    
    #日本語
    app.config['JSON_AS_ASCII'] = False
    #CORS=Ajaxで安全に通信するための規約
    api = Api(app)
    CORS(app)
    
    UPLOAD_FOLDER = './uploads'
    app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
    
    # 任意のリクエストを受け取った時、index.htmlを参照
    @app.route('/', defaults={'path': ''})
    @app.route('/<path:path>')
    def index(path):
        return render_template("index.html")
    
    @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)
    
    # app.run(host, port):hostとportを指定してflaskサーバを起動
    if __name__ == '__main__':
        app.run(host='0.0.0.0', port=5000)
    

    모습





    이런 느낌

    매우 도움이되었습니다.



    htps : //로 ゔぇぺぺr. 모잖아. 오 rg / 그럼 / cs / u b / Ht tP / RS
    이미지를 POST, 얼굴 감지, 캔버스로 얼굴에 그리기

    좋은 웹페이지 즐겨찾기