繁体   English   中英

将图像从烧瓶放入 HTML5 画布

[英]Putting an image from flask to an HTML5 Canvas

我正在尝试在 HTML5 画布上显示在我的 python 后端生成的图像。

我尝试过的烧瓶代码的两种变体:

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")

不同的 JS 尝试之一:

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);

我的另一个 JS 尝试从图像中剥离了标题信息,但也没有骰子。

我收到Uncaught DOMException: Failed to construct 'ImageData': The source width is zero or not a number. 除其他问题外。 我如何将数据从python发送到js?

通过这个最小的工作示例,我可以在画布上看到图像。

如果您访问主页http://localhost:5000/然后脚本将从http://localhost:5000/api/a加载图像并在画布上绘制。

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()

要将Image to转换Image to ImageData, you have to draw it on画布you have to draw it on

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
};

我从使用画布进行像素操作中获取的有关画布的信息


编辑:生成图像并发送而不保存在磁盘上。

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')

画布上的图像数据

完整代码:

from flask import Flask, send_file

import numpy as np
from PIL import Image
import io


app = Flask(__name__)


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

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

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

img.onload = function() {
  img.style.display = 'none'; // I don't know why they hide it

  console.log('WxH: ' + img.width + 'x' + img.height)

  // convert Image to ImageData
  //(it has to draw on canvas so it could need second canvas for this)

  ctx.drawImage(img, 0, 0);
  var imageData = ctx.getImageData(0, 0, img.width, img.height)

  //put ImageData many times  
  for(x = 0 ; x < 100 ; x += 10) {
    for(y = 0 ; y < 100 ; y += 10) {
       ctx.putImageData(imageData, x, y);
    }
  }
};
</script>
</body>
</html>
'''


@app.route('/api/b')
def array():
    '''
    generate image from numpy.array using PIL.Image
    and send without saving on disk using io.BytesIO'''

    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 as PNG in file in memory
    file_object.seek(0)          # move to beginning of file
                                 # so send_file() will read data from beginning of file

    return send_file(file_object,  mimetype='image/png')


app.run()

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM