开发者

Mask for putImageData with HTML5 canvas?

I want to take an irregularly shaped section from an existing image and render it as a new image in Javascript using HTML5 canvases. So, only the data inside the polygon boundary will be copied. The approach I came up with involved:

  1. Draw the polygon in a new canvas.
  2. Create a mask using clip
  3. Copy the data from the original canvas using getImageData (a rectangle)
  4. Apply the data to the new canvas using putImageData

It didn't work, the entire rectangle (e.g. the stuff from the source outside the boundary) is still appearing. This question explains why: "The spec says that putImageData will not be affected by clipping regions." Dang!

I also tried drawing the shape, setting context.globalCompositeOperation = "source-in", and then using putImageData. Same result: no mask applied. I suspect for a similar reason.

Any suggestions on how to accomplish this goal? Here's basic code for my work in progress, in case it's not clear what I'm trying to do. (Don't try too hard to debug this, it's cleaned up/extracted from code that uses a lot of functions that aren't here, just trying to show the logic).

 // coords is the polygon data for the area I want
   context = $('canvas')[0].getContext("2d");
   context.save();
   context.beginPath();
   context.moveTo(coords[0], coords[1]);
   for (i = 2; i < coords.length; i += 2) {
     context.lineTo(coords开发者_开发百科[i], coords[i + 1]);
   }
   //context.closePath();
   context.clip();

   $img = $('#main_image');
   copy_canvas = new_canvas($img); // just creates a new canvas matching dimensions of image
   copy_ctx = copy.getContext("2d");

   tempImage = new Image();
   tempImage.src = $img.attr("src");
   copy_ctx.drawImage(tempImage,0,0,tempImage.width,tempImage.height);

  // returns array x,y,x,y with t/l and b/r corners for a polygon
  corners = get_corners(coords)
  var data = copy_ctx.getImageData(corners[0],corners[1],corners[2],corners[3]);
  //context.globalCompositeOperation = "source-in";
  context.putImageData(data,0,0);
  context.restore();


dont use putImageData,

just make an extra in memory canvas with document.createElement to create the mask and apply that with a drawImage() and the globalCompositeOperation function (depending on the order you need to pick the right mode;

I do something similar here the code is here (mind the CasparKleijne.Canvas.GFX.Composite function)

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜