1
0

More than 3 years have passed since last update.

flask と socket.ioで2つの画像を合成する

Posted at

概要

canvasのデータをflask_socketioで、送り
サーバー側でbase64デコード、numpyにして
opencvで合成し、再度base64にエンコードして送り返す
いろいろ試しましたが、この方法じゃないと、ノイズが出たりとうまくいきませんでした。

環境

mac10.15
python3.9.2

template

top.html
<html>
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
            <script src="https://cdn.socket.io/3.1.3/socket.io.min.js" integrity="sha384-cPwlPLvBTa3sKAgddT6krw0cJat7egBga3DJepJyrLl4Q9/5WLra3rrnMcyTyOnh" crossorigin="anonymous"></script>

    </head>
    <body>
        <br>
        <button id="scan">scan</button>
        <br>
        <img  id="img1" src="{{ url_for('static', filename = 'bg.jpg') }}" width=300 height=200>
        <img  id="img2" src="{{ url_for('static', filename = '02.jpg') }}" width=300 height=200>     
        <canvas id="compimg" width=300 height=200></canvas>
    </body>

    <script>

    const imgw = 300;
    const imgh = 200;

    var scanButton = document.getElementById('scan');
    scanButton.addEventListener('click', function() {

        const canvas1 = document.createElement("canvas");
        canvas1.width = imgw;
        canvas1.height = imgh;
        const img1 = document.getElementById("img1");
        const ctx1 = canvas1.getContext("2d");
        ctx1.drawImage(img1, 0, 0);
        const canvas1data = canvas1.toDataURL("image/jpeg");

        const canvas2 = document.createElement("canvas");
        canvas2.width = imgw;
        canvas2.height = imgh;
        const img2 = document.getElementById("img2");
        const ctx2 = canvas2.getContext("2d");
        ctx2.drawImage(img2, 0, 0);
        const canvas2data = canvas2.toDataURL("image/jpeg");


        socket.emit( 'image', canvas1data, canvas2data);

    });

    const socket = io.connect();
     socket.on('connect', () => {
        console.log('connect');
    }); 

    socket.on('response', function(msg) {


        console.log('response');
        const compimg = document.getElementById('compimg');
        const compimgCtx = compimg.getContext('2d')

        var itemimage = new Image();
        itemimage.src= "data:image/jpeg;base64,"+msg.image;
        itemimage.onload = function () {      
            compimgCtx.drawImage(itemimage, 0, 0, imgw, imgh)
        }



    });



    </script>

</html>

flask

app.py
from flask import Flask, render_template, request
from flask_socketio import SocketIO, emit, disconnect

import cv2
import numpy as np
import base64
from PIL import Image
import io

app = Flask(__name__)
async_mode = None 
socketio = SocketIO(app, async_mode=async_mode,async_handlers=True)

@socketio.event
def connect():
    print("connect")

@app.route('/')
def top():
    return render_template('top.html')

@socketio.event
def image(img_base64,imgbg_base64):#base64
    print("recieve")
    im = Image.open(io.BytesIO(base64.b64decode(img_base64.split(',')[1])))
    imbg = Image.open(io.BytesIO(base64.b64decode(imgbg_base64.split(',')[1])))

    img1 = np.array(im)
    h,w = img1.shape[:2]
    imbgresize =  imbg.resize((w, h))
    img2 = np.array(imbgresize)

    dst = img1 * 0.5 + img2 * 0.5

    if dst is None:
        print("Image is empty!!")
    else:
        print("Image")
        buffer = io.BytesIO()
        Image.fromarray(dst.astype(np.uint8)).save(buffer, format="JPEG")
        new_image = base64.b64encode(buffer.getvalue()).decode("ascii")
        emit('response',{'image': new_image})

if __name__ == "__main__":
    app.run( port=8000, debug=True)

使用した素材

完成

gif

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0