CanvasRenderingContext2D.putImageData 的参数 1 未实现接口 ImageData

Argument 1 of CanvasRenderingContext2D.putImageData does not implement interface ImageData

大家好,我正在尝试使用 node.js 制作一个 html5 cavas 应用程序,但我遇到了一个问题,我正在使用 getImagedata() 获取图像数据并将其作为 [=20] 发送到服务器=] 对象到服务器,该服务器将把该对象传递给所有连接的客户端,但我在所有其他客户端上收到 "Argument 1 of CanvasRenderingContext2D.putImageData does not implement interface 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);
 });

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

此外,由于图像数据是类型化数组而不是常规数组,因此数据将被转换为 object,其中每个索引都是 属性。 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 object 转换 Uint8ClampedArray,但由于每个索引最终都会成为 属性,因此发送和接收时放回原处的成本会更高。

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

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

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