I want to take an irregularly shaped section from an existing image and make it like a new image in Javascript using HTML5 canvases. Thus, only data inside the polygon border will be copied. The approach I came up with:
- Draw a polygon in a new canvas.
- Create a mask with
clip - Copy data from source canvas using
getImageData (rectangle) - Apply data to a new canvas with
putImageData
This did not work, the entire rectangle (for example, material from the source outside the border) still appears. This question explains why: "The spectrum says putImageData will not suffer from clipping regions." Dang!
I also tried drawing the shape by setting context.globalCompositeOperation = "source-in" and then using putImageData . Same result: no mask applied. I suspect for the same reason.
Any suggestions on how to achieve this? Here is the basic code for my work, if it is not clear what I am trying to do. (Do not try to debug this too hard, it is cleared / extracted from code that uses many functions that are not 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();
source share