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:
clip
getImageData
(a rectangle)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)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With