Quiero tomar una sección de forma irregular de una imagen existente y presentarla como una imagen nueva en Javascript utilizando lienzos HTML5. Por lo tanto, solo se copiarán los datos dentro del límite del polígono. El enfoque que surgió involucró:Máscara para putImageData con canvas HTML5?
- Dibuje el polígono en un lienzo nuevo.
- Crear una máscara usando
clip
- copiar los datos de la tela original utilizando
getImageData
(un rectángulo) - aplicar los datos a la nueva lienzo utilizando
putImageData
No funcionó, la totalidad rectángulo (por ejemplo, las cosas de la fuente fuera del límite) todavía está apareciendo. This question explica por qué: "La especificación dice que putImageData
no se verá afectado por las regiones de recorte". ¡Dang!
También traté de dibujar la forma, estableciendo context.globalCompositeOperation = "source-in"
, y luego usando putImageData
. Mismo resultado: sin máscara aplicada. Sospecho por una razón similar.
¿Alguna sugerencia sobre cómo lograr este objetivo? Aquí hay un código básico para mi trabajo en progreso, en caso de que no esté claro lo que intento hacer. (No intente depurarlo demasiado, se limpia/extrae del código que usa muchas funciones que no están aquí, solo intenta mostrar la lógica).
// 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();
impresionante! ¡Funciona! Muchas gracias. –
Pregunta rápida: ¿Puedes pensar en una forma de hacerlo sin tres temporeros? lienzos? Tengo 1 para cargar una copia de la imagen principal, luego una para copiar el rectángulo, y la tercera que tiene la máscara, a la que aplico la 2da. Siento que debo estar haciendo demasiado en alguna parte, pero no puedo pensar en una forma de ir directamente de la imagen completa a un lienzo que contenga solo el rectángulo. –
En el código que incluí, puede compilar un Composite que pueda mostrar una lista de tantos lienzos como desee, sin embargo, le aconsejo que lo haga con cuidado desde el punto de vista del rendimiento. Así que probar y probar es una buena práctica;) –