【问题标题】:Argument 1 of CanvasRenderingContext2D.putImageData does not implement interface ImageDataCanvasRenderingContext2D.putImageData 的参数 1 没有实现接口 ImageData
【发布时间】:2015-05-09 03:05:15
【问题描述】:

大家好,我正在尝试使用 node.js 制作一个 html5 cavas 应用程序,但我遇到了一个问题,我正在使用 getImagedata() 获取图像数据并将其作为 JSON 对象发送到服务器,然后服务器将传递该对象到所有连接的客户端,但我收到“CanvasRenderingContext2D.putImageData 的参数 1 未实现接口 ImageData。”所有其他客户端上的错误。任何帮助将不胜感激 以下是发送图片的客户端代码:

var output = function(mousestartposition , currentmouseposition){
  **lastpositionpic = context.getImageData(0,0,canvas.width ,      canvas.height);**
    var data = {
        mousestartposition : mousestartposition ,
        currentmouseposition:currentmouseposition,
        lastpositionpic : lastpositionpic
    }
    socket.emit('senddraw' , data);
 }

接收图片的客户端代码如下:

 socket.on('receivedraw' , function(data)
 {
     mousestartposition = data.mousestartposition;
     var currentmouseposition = data.currentmouseposition;
     lastpositionpic = data.lastpositionpic;
     **context.putImageData(lastpositionpic,0,0);** // i am getting error on this line
     draw(currentmouseposition);
 });

【问题讨论】:

    标签: javascript html node.js html5-canvas


    【解决方案1】:

    当您尝试使用 JSON 序列化 ImageData 对象时会出现问题。任何对象类型信息都将被剥离,因此当您尝试在接收时解析它时,数据将只是一个普通对象。

    此外,由于图像数据是类型数组而不是常规数组,因此数据将被转换为一个对象,其中每个索引都是一个属性。 ImageData 还包含无法序列化的方法。

    您需要做的是在发送前转换您的数据:

    lastpositionpic = context.getImageData(0,0,canvas.width, canvas.height);
    
    var pic = [];
    for(var i = 0; i < lastpositionpic.length; i++) pic.push(lastpositionpic[i]);
    
    var data = {
        width: canvas.width,
        height: canvas.height,
        mousestartposition : mousestartposition ,
        currentmouseposition:currentmouseposition,
        lastpositionpic : pic
    }
    socket.emit('senddraw' , data);
    

    收到后返回:

    socket.on('receivedraw' , function(data)
    {
         mousestartposition = data.mousestartposition;
         var currentmouseposition = data.currentmouseposition;
         lastpositionpic = data.lastpositionpic;
    
         var idata = context.createImageData(data.width, data.height);
         for(var i = 0; i < idata.data.length; i++) idata.data[i] = lastpositionpic[i];
    
         context.putImageData(idata,0,0);
         draw(currentmouseposition);
     });
    

    现在,这里涉及到性能损失,因为您必须转换和转换。如前所述,您也可以直接从 ImageData 对象转换 Uint8ClampedArray,但由于每个索引最终都会成为一个属性,因此发送和接收时重新组合起来的成本会更高。

    我对 Node.js 上的套接字不是很熟悉,但如果与任何其他套接字一样,您可能会有一种直接发送二进制数据的方法 (turns out you can)。

    如果是这种情况,我建议创建一个大小为 Uint16 x 2 + Int16 x 2(宽度、高度、鼠标 x、鼠标 y)加上 ImageData 位图大小的类型化数组,写入宽度和高度、鼠标位置在该数组的标题中,然后在其后写入数据本身。

    这将是发送此类数据的最高效方式。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-10-07
      • 1970-01-01
      • 1970-01-01
      • 2016-08-17
      • 1970-01-01
      相关资源
      最近更新 更多