javascript HTML5 canvas display from python websocket server

人盡茶涼 提交于 2019-12-25 12:44:56

问题


I created a websocket server that uses ZeroMQ4 to talk to a middleware. I also created a peice of Javascript to display information back from the middleware.

I know the Websocket server works and is able to send to the javascript as i tested with small string output.

So, I want to send an png image from the websocket server to Javascript, but the Javascript documentation of canvas is confusing and I haven't found a solid example good for a newbie with Javascript.

This is the Javascript I have so far it is able to input data in, but does not display any image.

var canvas = document.getElementById('stage');
var context = canvas.getContext("2d");

function openWS(){
    var websocket = new WebSocket("ws://raptorweb1.no-ip.org:10000");
    websocket.binaryType = "arraybuffer";
    websocket.onmessage = function(evt) { onMessage(evt) };
    websocket.onerror = function(evt) { onError(evt) };
    websocket.onopen = function(evt) { onOpen(evt) };
    function onOpen(evt){
        var luser = document.getElementById("lusername").value;
        var ruser = document.getElementById("rusername").value;
        var pwd = document.getElementById("password").value;
        console.log("Connecting.. ");
        websocket.send("SUB[00100]" + luser);
        websocket.send("MESSAGE[00100]" + ruser + "[11111]" + pwd);
        console.log("Connected.");
    }

    function onMessage(evt) {
        console.log("received: " + evt.data);
        drawImageBinary(evt.data);
    }

    function onError(evt) {
        console.log(evt.data);
    }


    function drawImageBinary(blob) {
        var bytes = new Uint8Array(blob);
        // console.log('drawImageBinary (bytes.length): ' + bytes.length);
        var imageData = context.createImageData(canvas.width, canvas.height);
        for (var i=8; i<imageData.data.length; i++) {
            imageData.data[i] = bytes[i];
        }
        context.putImageData(imageData, 0, 0);
        var img = document.createElement('img');
        //img.height = canvas.height;
        //img.width = canvas.width;
        img.src = canvas.toDataURL();
    }
}

this is the websocket server:

clients = []
from SimpleWebSocketServer import WebSocket, SimpleWebSocketServer,     SimpleSSLWebSocketServer
import zmq
import zmq.auth
from zmq.auth.thread import ThreadAuthenticator
import sys
import os
import random
import pygame
from pygame.locals import *
import base64
import string
from threading import Thread
def id_generator(size=10, chars=string.ascii_uppercase + string.digits):
    return ''.join(random.choice(chars) for _ in range(size))
class SimpleChat(WebSocket):
    def initZMQ(self):
        file = sys.argv[0]
        base_dir = os.path.dirname(file)
        keys_dir = os.path.join(base_dir, 'certificates')
        public_keys_dir = os.path.join(base_dir, 'public_keys')
        secret_keys_dir = os.path.join(base_dir, 'private_keys')
        self.context = zmq.Context()
        self.socket = self.context.socket(zmq.DEALER)
        client_secret_file = os.path.join(secret_keys_dir, "client.key_secret")
        client_public, client_secret = zmq.auth.load_certificate(client_secret_file)
        self.socket.curve_publickey = client_public
        self.socket.curve_secretkey = client_secret
        server_public_file = os.path.join(public_keys_dir, "server.key")
        server_public, _ = zmq.auth.load_certificate(server_public_file)
        self.socket.curve_serverkey = server_public
        self.width = "0"
        self.height = "0"
    def ondata(self):
        while True:
            try:
                data = self.socket.recv()
                code, self.width = data.split('[55555]')
                data = self.socket.recv()
                code, self.height = data.split('[55555]')
                self.width = int(self.width)
                self.height = int(self.height)
                self.width = float(self.width /1.5)
                self.height = float(self.height /1.5)
                print (self.width, self.height)
                data = self.socket.recv()   
                image = pygame.image.frombuffer(data, (int(self.width),int(self.height)),"RGB")
                randname = id_generator()
                pygame.image.save(image,randname+".png")
                out = open(randname+".png","rb").read()
                self.sendMessage(out)
                print("data sent")
                os.remove(randname+".png")
            except Exception as e:
                print (e)
    def handleMessage(self):
       try:
           message = str(self.data) 
           protocode, msg = message.split("[00100]")
           if protocode == ("SUB"):
               print("SUB")
               self.socket.setsockopt(zmq.IDENTITY, str(msg))
               self.socket.connect("tcp://127.0.0.1:9001")
               Thread(target=self.ondata).start()
           elif protocode == ("MESSAGE"):
               print("MESSAGE")
               msg = str(msg)
               ident, mdata = msg.split("[11111]")
               msg = ('%sSPLIT%s' % (ident, mdata))
               self.socket.send(str(msg))
           else:
               raise Exception
       except Exception as e:
           print (e)

    def handleConnected(self):
       print (self.address, 'connected')
       clients.append(self)
       self.initZMQ()


    def handleClose(self):
       clients.remove(self)
       print (self.address, 'closed')
       for client in clients:
          client.sendMessage(self.address[0] + u' - disconnected')

server = SimpleWebSocketServer('', 10000, SimpleChat)
server.serveforever()

回答1:


I managed to solve this problem.

Turns out that my javascript and my python server were wrong.

this is the function that works for me when processing the message from the server:

function onMessage(evt) {
        var img = new Image();
        img.src = "data:image/png;base64,"+evt.data;
        img.onload = function () {
            context.drawImage(img,0,0);
        }
}

I had to add a base64.b64encode on my server right before I send the picture.



来源:https://stackoverflow.com/questions/32595130/javascript-html5-canvas-display-from-python-websocket-server

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!