Putting an image from flask to an HTML5 Canvas

by user10011538   Last Updated July 13, 2019 01:26 AM

I'm trying to display an image generated in my python backend on an HTML5 canvas.

Two variants of the flask code I tried:

1)

@app.route(r'/api/a', methods=["GET", "POST"])
def send_heatmap():
           return open(r"..\\a\\b\\50.png", "rb").read()

2)

@app.route(r'/api/a', methods=["POST"])
def send_heatmap():
    img = io.BytesIO(open(r"..\\a\\b\\50.png", "rb").read())
    return send_file(img, mimetype='image/png', as_attachment=True, attachment_filename="heatmap.png")

One of the different JS attempts:

console.log(result);
var canvas = document.getElementsByTagName('canvas');
context = canvas[1].getContext('2d');
var a = new ImageData(result["content"], 480)
context.putImageData(a, 0, 0);

Another of my JS attempts stripped the header information from the image but also no dice.

I receive Uncaught DOMException: Failed to construct 'ImageData': The source width is zero or not a number. Among other problems. How am I to send the data from python to js?



Answers 1


With this minimal working example I can see image on canvas.

If you visit main page http://localhost:5000/ then script will load image from http://localhost:5000/api/a and draw on canvas.

from flask import Flask, send_file


app = Flask(__name__)


@app.route('/api/a')
def image():
    return send_file('/home/user/images/ball.png',  mimetype='image/png')


@app.route('/')
def index():
    return '''
<canvas></canvas>
<script>
var canvas = document.getElementsByTagName('canvas');
var ctx = canvas[0].getContext('2d');

var img = new Image();
img.src = "/api/a";

// it can't draw it at once. it has to wait till image is loaded
//ctx.drawImage(img, 0, 0);

img.onload = function() {
   img.style.display = 'none'; // I don't know why they hide it 
   ctx.drawImage(img, 0, 0);   // draw on canvas
};
</script>
'''

app.run()

To convert Image toImageDatayou have to draw it oncanvas`.

img.onload = function() {
  console.log('WxH: ' + img.width + 'x' + img.height)

  img.style.display = 'none';  // hide it

  ctx.drawImage(img, 0, 0);  // draw Image on canvas

  var imageData = ctx.getImageData(0, 0, img.width, img.height);  // get ImageData from canvas

  ctx.putImageData(imageData, 10, 10);  // put ImageData in differen place
};

Infomation about canvas I took from Pixel manipulation with canvas


EDIT: generated image

import numpy as np
from PIL import Image
import io

@app.route('/api/a')
def array():
    arr = np.array([
        [255, 255,   0,   0,   0,   0,   0,   0, 255, 255],
        [255,   0, 255, 255, 255, 255, 255, 255,   0, 255],
        [  0, 255, 255, 255, 255, 255, 255, 255, 255,   0],
        [  0, 255, 255,   0, 255, 255,   0, 255, 255,   0],
        [  0, 255, 255, 255, 255, 255, 255, 255, 255,   0],
        [  0, 255, 255, 255, 255, 255, 255, 255, 255,   0],
        [  0, 255,   0, 255, 255, 255, 255,   0, 255,   0],
        [  0, 255, 255,   0,   0,   0,   0, 255, 255,   0],
        [255,   0, 255, 255, 255, 255, 255, 255,   0, 255],
        [255, 255,   0,   0,   0,   0,   0,   0, 255, 255],
    ])

    img = Image.fromarray(arr.astype('uint8')) # convert arr to image

    file_object = io.BytesIO()   # create file in memory 
    img.save(file_object, 'PNG') # save PNG in file in memory
    file_object.seek(0)          # move to beginning of file

    return send_file(file_object,  mimetype='image/png')
furas
furas
July 13, 2019 00:27 AM

Related Questions