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

时间:2015-03-07 16:12:49

标签: javascript html node.js html5-canvas

大家好我想用node.js制作一个html5 cavas应用程序,但我遇到问题我使用getImagedata()获取imagedata并将其作为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);
 });

1 个答案:

答案 0 :(得分:2)

当您尝试使用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上的socket并不熟悉,但是如果像其他任何套接字一样,你可能有办法直接发送二进制数据(turns out you can)。

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

这是发送此类数据的最佳方式。