使用nodeJS的跨浏览器canvas没有find函数的签名

我试图在页面上创build一个canvas,每当用户在上面画一些东西时就会自动更新。 但是,看起来好像下面的一段代码(来自index.html)导致错误

socket.on("drawn_complete",function(data){ ctx.putImageData(data.image,0,0); console.log("Everthing worked technically"); }); 

这是在我的控制台输出的错误:

 Uncaught TypeError: Failed to execute 'putImageData' on 'CanvasRenderingContext2D': No function was found that matched the signature provided 

我的data.image是从以下代码返回的内容:

 ctx.getImageData(0,0,200,100); // ctx is canvas.getContext("2d") 

这是我的canvas在我的HTML:

  <canvas id="myCanvas" width="200" height="100" style="border:1px solid #000000;"> </canvas> 

这里是完整的节点JS:

  var http = require("http") var server = http.createServer(handler).listen(1337); console.log("Server created at 127.0.0.1:1337"); var io = require("socket.io").listen(server); function handler(req,res) { console.log("Client Connected"); res.writeHead(200,{"Content-type": "text/plain"}); res.end("Hello World"); } io.sockets.on("connection",function(socket){ socket.on("drawing",function(data){ var image = data["image"]; io.sockets.emit("drawn_complete",image); }); }); 

当用户在我的canvas中按住并移动鼠标时,绘图将被消除:

这里是代码:

  c.onmousedown = function(evt){ moving = true }; c.onmousemove = function(evt){ if(moving == true) { console.log("holding and moving"); var x = evt.clientX - rect.left; var y = evt.clientY - rect.top; console.log("X: " + x + " Y: " + y); ctx.fillRect(x,y,1,1); socket.emit("drawing",{"image": ctx.getImageData(0,0,200,100)}); } }; c.onmouseup = function(evt){ moving = false; }; 

UPDATE

这里是enitre脚本:

 <script> window.onload = function(){ var socket = io.connect("http://localhost:1337"); socket.on("drawn_complete",function(data){ ctx.putImageData(data.image,0,0); console.log("Everthing worked technically"); }); var c = document.getElementById("myCanvas"); var moving = false; console.log(c); var ctx = c.getContext("2d"); var rect = c.getBoundingClientRect(); c.onmousedown = function(evt){ moving = true }; c.onmousemove = function(evt){ if(moving == true) { console.log("holding and moving"); var x = evt.clientX - rect.left; var y = evt.clientY - rect.top; console.log("X: " + x + " Y: " + y); ctx.fillRect(x,y,1,1); socket.emit("drawing",{"image": ctx.getImageData(0,0,200,100)}); } }; c.onmouseup = function(evt){ moving = false; }; }; </script> 

更新由于Palanikbuild议我发现它之前序列化图像:

  var stringfy = JSON.stringify(ctx.getImageData(0,0,200,100)); socket.emit("drawing",{"image": stringfy}); 

看起来好像控制台仍然抛出相同的错误

更新(2)作为@Palanikbuild议我试图序列化的对象。 我知道下面的代码并不是他推荐的,但我只想强调一些非常奇特的东西:

发件人:

 var stringfy = ctx.getImageData(0,0,200,100); console.log(stringfy) var sent = JSON.stringify(stringfy); socket.emit("drawing",{"image": sent}); 

Reciever

 socket.on("drawn_complete",function(data){ imageData = JSON.parse(data.image); console.log(imageData); ctx.putImageData(imageData,0,0); console.log("Everthing worked technically"); 

});

这里有趣的是,imageData的console.log打印出一个与ImageData具有相同属性的对象。 高度,宽度和原始。 看看这里:

 {"height":100,"width":200,"data":{"0":0,"1":0,"2":0,"3":0,"4":0,"5 etc... } 

所以我从这里可以看到我能够把对象拿回来。 如果我在java中,演员就足够了。

 ImageData object = (ImageData) imageData // Is there a way to do this? 

这里的解决scheme是使用canvas.toDataURL();

这将返回一个Base64编码的图像string(在MIMEtypes和编码的头)。

 var canvas = getMyCanvas(), ctx = canvas.getContext("2d"), encodedImageData = canvas.toDataURL(), image = new Image(); image.src = encodedImageData; ctx.drawImage(image, x, y, w, h...); 

您可以愉快地将这些编码的string传递给服务器和从服务器传递。
您也可以在普通的HTML <img src="data:image/png;base64,...">使用它们。

另外,你可以传递给toDataURL几个参数:

  canvas.toDataURL("image/jpeg", 0.5);` 

其中,第一个参数是请求的文件types,第二个参数是请求的图像质量级别(介于0和1之间)。

不过,不能保证任何浏览器都能支持你所要求的东西,不pipe怎么说,无论如何你可能只会得到一个.png文件(无论如何,这可能是你想要的一个游戏,透明度)。

此外,Android 2.2浏览器和更低,和IE9,我觉得移动Safari 5.1(原来的iPad),不支持.toDataURL
我可能是iPad的错,但他们不支持其他有用的HTML5 API。

ImageData可能不可移植。 尝试在发送和反序列化之前序列化imagedata,并在接收端创buildimagedata。

===更新===

就像是 :

寄件人

 canvasData = ctx.getImageData(0,0,200,100)} myData = { height : canvasData.height, width : canvasData.width, raw : canvasData.data }; socket.emit("drawing",{"image": myData}); 

接收器

 imgData = ctx.getImageData(myData.width, myData.height); for (var i = 0; i < myData.raw.length) { imgData.data[i] = myData.raw[i]; } ctx.putImageData(imgData, 0, 0); 

这是未经testing的代码。 只是一个想法让你尝试一下。