使用context.putImageData()仅复制画布的一部分

时间:2015-05-09 16:31:01

标签: javascript html5 canvas

我试图一块一块地迭代填充画布。此外,我希望用原始图像的正方形迭代填充画布。

出于性能原因,我首先将原始图像渲染到屏幕外画布,然后使用getImageData()获取imagedata。

在屏幕画布上,我尝试使用以下代码迭代绘制片段:

        var x = 0;
        var y = 0;
        for (var i = 0; i <= (nbPiecesHorizontal*nbPiecesVertical-1); i++) {

            onscreenContext.putImageData(
                offScreenData.imageData, 
                x*pieceWidth, 
                y*pieceHeight, 
                x*pieceWidth, 
                y*pieceHeight, 
                pieceWidth, 
                pieceHeight);


            // iter
            x = x + 1;
            if (x == (nbPiecesHorizontal)) {
                x = 0;
                y = y +1;
            }
        };

然而,我只能得到几件作品,更具体的是角落中的作品。我想要偏离所有要绘制的部分。我怎么解决这个问题?

1 个答案:

答案 0 :(得分:3)

使用.getImageData.putImageData是绘制到画布的缓慢而昂贵的方法,因为它们在像素级别操作画布。

将图像逐渐绘制到画布的更好方法是使用context.drawImage的剪切版本。 drawImage的剪切版本将剪切原始图像的指定部分并将其绘制到画布上。

使用drawImage要快得多,因为像素只是从源图像复制到目标画布而不是通过额外的“过滤器”像素操作。

以下是drawImage的剪辑版本的工作原理:

context.drawImage(

    sourceImage,  // the source image to clip from

    sX,           // the left X position to start clipping 
    sY,           // the top Y position to start clipping
    sW,           // clip this width of pixels from the source
    wH,           // clip this height of pixels from the source

    dX,           // the left X canvas position to start drawing the clipped sub-image
    dY,           // the top Y canvas position to start drawing the clipped sub-image
    dW,           // scale sW to dW and draw a dW wide sub-image on the canvas
    dH            // scale sH to dH and draw a dH high sub-image on the canvas

}

示例代码和演示:

var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");

var nextTime=0;
var duration=500;
var nextX=0;
var nextY=0;
var cols=5;
var rows=3;
var iw,ih,colWidth,rowHeight;

var img=new Image();
img.onload=start;
img.src="https://dl.dropboxusercontent.com/u/139992952/multple/annotateMe.jpg";
function start(){
  iw=canvas.width=img.width;
  ih=canvas.height=img.height;
  colWidth=iw/cols;
  rowHeight=ih/rows;
  requestAnimationFrame(animate);
}


function animate(time){

  // check if the elapsed time has reached nextTime
  // if not, just request another animation loop
  if(time<nextTime){requestAnimationFrame(animate); return;}

  // reset nextTime 
  nextTime=time+duration;

  // calc the x,y of the subimage to clip from the whole img
  var x=parseInt(nextX*colWidth);
  var y=parseInt(nextY*rowHeight);

  // clip the subimage from the source image
  // and draw the subimage onto the canvas
  ctx.drawImage(
    // use img as the source for clipping
    img,
    // clip the next cell from the img at x,y 
    // and clip out a subimage with size colWidth x rowHeight
    x,y,colWidth,rowHeight,
    // draw the clipped subimage to the canvas
    x,y,colWidth,rowHeight
  );

  // calc the next subimage x,y for the next loop
  var imageIsComplete=false;
  nextX++;
  if(nextX>cols-1){
    nextX=0;
    nextY++;
    if(nextY>rows-1){ imageIsComplete=true; }
  }

  // if the image is not complete, request another loop
  if(!imageIsComplete){ requestAnimationFrame(animate); }

  if(imageIsComplete){alert('Image is complete!');}

}
body{ background-color: ivory; }
#canvas{border:1px solid red;}
<canvas id="canvas" width=300 height=300></canvas>