如何通过节点js发送div?

时间:2016-09-26 23:12:47

标签: javascript html node.js canvas

上下文: 我正在创建一个Web应用程序,我可以在画布上绘制,将其另存为图像,然后通过Node将其发送到另一个客户端。

什么有效:

  • 绘图(在任一客户端上。它会实时更新)。
  • 将画布保存为Uint8Array
  • 将画布保存为img div w / base64编码图像

我被困的地方:

我似乎无法将完成的图像传输给其他客户端。我能够以各种方式保存画布,但不知道如何将其画出来。

我如何将其作为div发送到节点服务器:

   byId('sendHTML').onclick = SendImageHTML;  
   function SendImageHTML() {    
        var imageHTML = convertCanvasToImage(canvas); 
        socket.emit('SendImageHTML', imageHTML);
        // EMITS: <img src="data:image/png;base64, iVB9023423523345346....."
   }

发送为Uint8Array:

  /**
   * Converts canvas to bytes & emits web socket message
   * @return {Uint8Array} Bytes from canvas 
   */     
  byId('defImgBinary').onclick = DefineImageBinary;  
  function DefineImageBinary() {
        var image  = context.getImageData(0, 0, canvas.width, canvas.height);
        var buffer = new ArrayBuffer(image.data.length);
        var bytes  = new Uint8Array(buffer);

        for (var i=0; i<bytes.length; i++) {
            bytes[i] = image.data[i];
        }

        socket.emit('defImgBinary', bytes);
        // EMITS: [24, 24, 29, 255, 24, 24, 29, 255, 24, 24.......]

  }

这是我的服务器代码:

socket.on('SendImageHTML', function (html) {
    console.log("SendImageHTML called: ");
    log(html);
    // RETURNS:
    // SendImageHTML called:
    // {} 
});




socket.on('defImgBinary', function (bytes) {
    log("defImgBinary called: ");
    log(bytes);
    // RETURNS:
    // defImgBinary called:
    // '53721': 220,
    // '53722': 219,
    // '53723': 255,
    // '53724': 229,
});

我需要帮助:

我从那里做什么?如何在其他客户端上将其显示为图像?

1 个答案:

答案 0 :(得分:3)

如果您使用Canvas API中的getDataURL()然后发送base64编码图像或呈现的DOM元素,那么您会满意吗?

在客户端:

您可以通过HTMLCanvasElement.toDataURL从画布中获取base64编码的数据。这将导致以data:image/png;base64...开头的字符串,就像在代码示例中一样。

获取字符串后,您可以将其作为String直接发送到服务器,或将其呈现为Image元素:

var image = new Image(width, height);
image.src = myBase64String;

image.addEventListener('load', function () { /* NOTE On image loaded */ });

如果要将呈现的DOM元素发送到服务器,您可能会发现Element.outerHTML非常有用 - 此属性将返回元素的精确字符串表示形式(例如"<img src="data:image/png;base64..." width="256" height="256" />")。< / p>

在服务器端:

在这两种情况下,您只需通过套接字将数据发送到其他客户端。

在其他客户方:

如果您发送一个简单的base64编码字符串,可以使用Image元素轻松呈现它:

var image = new Image(256, 256);
image.src = receivedBase64String;

image.addEventListener('load', function () { 
  document.appendChild(image);
});

如果发送已渲染的元素,可以使用document.createElement将其放入DOM结构中:

var image = document.createElement('div'); // NOTE Create a 'host' element
image.innerHTML = receivedRenderedElementString;

document.appendChild(image);

实施例

请参阅下面的代码以获取工作示例。

客户方:

<title>
  Canvas Sample
</title>
<p>
  <canvas id="sample-canvas" width="256" height="256"></canvas>
</p>
<p>
  <button id="send-canvas">
    Send canvas
  </button>
  <label for="send-as-div">
    <input type="checkbox" id="send-as-div">
      Send as div
    </input>
  </label>
</p>
<p id="output-console"></p>

<script src="https://cdn.socket.io/socket.io-1.4.5.js"></script>
<script>
  // NOTE Simple IO console element for socket communication
  let outputConsole = document.querySelector('#output-console');
  let printToConsole = (text = '') => {
    outputConsole.innerHTML += text + '<br/>';
  };
  let renderToConsole = (element) => {
    outputConsole.appendChild(element);
    outputConsole.innerHTML += '<br/>';
  };

  // NOTE Load image (random cat image)
  let image = new Image(250, 250);
  image.src = 'http://thecatapi.com/api/images/get?format=src&size=small';
  printToConsole('Image loading.');

  // NOTE Setup canvas
  // Render the cat image when it is loaded.
  let canvas = document.querySelector('#sample-canvas');
  let context = canvas.getContext('2d');

  image.addEventListener('load', () => {
    context.drawImage(image, 0, 0);
    printToConsole('Image loaded.');
  });

  image.addEventListener('error', (error) => {
    printToConsole('Image error.' + JSON.strinfify(error));
  });

  // NOTE Setup a websocket
  // Socket will allow to send 'img' message with either a base64 encoded
  // image data, or a rendered HTML Image element.
  let socket = io('ws://localhost:8080/');

  socket.on('error', (error) => {
    printToConsole('Socket error.' + JSON.stringify(error));
  });

  socket.on('img', (image) => {
    let renderedImage = null;

    if (image.indexOf('data:image/') === 0) {

      // NOTE If we receive a base64 image, we render it as an Image
      renderedImage = new Image(250, 250);
      renderedImage.src = image;
    } else {

      // NOTE If we receive a rendered <img> element, we render it directly
      // via document.createElement
      renderedImage = document.createElement('div');
      renderedImage.innerHTML = image;
    }

    printToConsole('Received image.');
    renderToConsole(renderedImage);
  });

  // NOTE Setup button
  let sendButton = document.querySelector('#send-canvas');

  sendButton.addEventListener('click', () => {
    let encodedCanvas = canvas.toDataURL();
    let sendAsDiv = document.querySelector('#send-as-div').checked;
    let payload = null;

    if (sendAsDiv) {
      let imageElement = new Image(250, 250);
      imageElement.src = encodedCanvas;

      payload = imageElement.outerHTML;
    } else {
      payload = encodedCanvas;
    }

    socket.emit('img', payload);

    printToConsole('Image sent.');
  });
</script>

服务器端(需要npm install -D express socket.io):

'use strict';

let express = require('express');
let http = require('http');
let socketIo = require('socket.io');

// NOTE Setup server
let httpServer = http.createServer(express());
let socketServer = socketIo(httpServer);
let sockets = [];
let port = 8080;

httpServer.listen(port);

// NOTE Setup socket listener

socketServer.on('connection', (socket) => {
  sockets.push(socket);

  let socketId = sockets.length;

  socket.on('img', (payload) => {
    socket.broadcast.emit('img', payload);
  });
});

如果能解决您的问题,请告诉我