Mask for putImageData with HTML5 canvas?

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(); 
+6
source share
1 answer

Do not use putImageData ,

just add extra memory to the canvas using document.createElement to create a mask and apply it using the drawImage() and globalCompositeOperation (depending on the order you need to choose in the correct mode;

I am doing something similar here code (remember the function CasparKleijne.Canvas.GFX.Composite )

+10
source

Source: https://habr.com/ru/post/887659/


All Articles