在尝试查找Canvas上下文的put
ImageData()方法的文档时,我发现了这样的事情:
context.putImageData(imgData,X,Y,dirtyX,dirtyY,dirtyWidth,dirtyHeight);
(自http://www.w3schools.com/tags/canvas_putimagedata.asp起)
根据我读过的文档,x和y是源图像的索引,而dirtyX和dirtyY指定目标画布中绘制图像的位置.然而,正如您将从下面的示例(和JSFiddle)中看到的,对putImageData(imgData,x,y)的调用有效,而putImageData(imgData,locX,locY)则没有.我不知道为什么.
编辑:
我想我真正的问题是为什么图像的顶行是黑色的,而且只有7行,而不是8.图像应该从画布的左上角开始.它们从左侧开始(并且有8列).为什么他们不从头顶开始?
答:当yLoc为0时,由于此行除以0:
xoff = imgWidth / (yLoc/3);
JSFiddle:
码:
<html> <head> <title>Canvas tutorial</title> <script type="text/javascript"> var canvas; var context; // The canvas's 2d context function setupCanvas() { canvas = document.getElementById('myCanvas'); if (canvas.getContext) { context = canvas.getContext('2d'); context.fillStyle = "black"; // this is default anyway context.fillRect(0,canvas.width,canvas.height); } } function init() { loadImages(); startGating(); } var images = new Array(); var gatingTimer; var curIndex,imgWidth=0,imgHeight; // Load images function loadImages() { for (n = 1; n <= 16; n++) { images[n] = new Image(); images[n].src = "qxsImages/frame" + n + ".png"; // document.body.appendChild(images[n]); console.log("width = " + images[n].width + ",height = " + images[n].height); } curIndex = 1; imgWidth = images[1].width; imgHeight = images[1].height; } function redrawImages() { if (imgWidth == 0) return; curIndex++; if (curIndex > 16) curIndex = 1; // To do later: use images[1].width and .height to layout based on image size for (var x=0; x<8; x++) { for (var y=0; y<8; y++) { //if (x != 1) // context.drawImage(images[curIndex],x*150,y*100); // context.drawImage(images[curIndex],y*100,imgWidth/2,imgHeight/2); // scale // else self.drawCustomImage(x*150,y*100); } } } function drawCustomImage(xLoc,yLoc) { // create a new pixel array imageData = context.createImageData(imgWidth,imgHeight); pos = 0; // index position into imagedata array xoff = imgWidth / (yLoc/3); // offsets to "center" yoff = imgHeight / 3; for (y = 0; y < imgHeight; y++) { for (x = 0; x < imgWidth; x++) { // calculate sine based on distance x2 = x - xoff; y2 = y - yoff; d = Math.sqrt(x2*x2 + y2*y2); t = Math.sin(d/6.0); // calculate RGB values based on sine r = t * 200; g = 125 + t * 80; b = 235 + t * 20; // set red,green,blue,and alpha: imageData.data[pos++] = Math.max(0,Math.min(255,r)); imageData.data[pos++] = Math.max(0,g)); imageData.data[pos++] = Math.max(0,b)); imageData.data[pos++] = 255; // opaque alpha } } // copy the image data back onto the canvas context.putImageData(imageData,xLoc,yLoc); // Works... kinda // context.putImageData(imageData,yLoc,imgWidth,imgHeight); // Doesn't work. Why? } function startGating() { gatingTimer = setInterval(redrawImages,1000/25); // start gating } function stopGating() { clearInterval(gatingTimer); } </script> <style type="text/css"> canvas { border: 1px solid black; } </style> </head> <body onload="setupCanvas(); init();"> <canvas id="myCanvas" width="1200" height="800"></canvas> </body> </html>
解决方法
你只是向后坐标.
context.putImageData(imageData,imgHeight);
xLoc和yLoc是放置它的地方,而0,imgHeight是你放在画布上的数据.
Another example显示了这一点.
许多在线文档似乎有点矛盾,但对于七个param版本
putImageData(img,dx,dy,dirtyRectWidth,dirtyRectheight)
dx和dy是你的目的地,接下来的四个参数是脏的rect参数,基本上控制你从源画布绘制的内容.我能找到的最全面的描述之一是Simon Sarris的HTML5 Unleashed(第165页).