2011-05-09 11 views
6

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?

  1. Dibuje el polígono en un lienzo nuevo.
  2. Crear una máscara usando clip
  3. copiar los datos de la tela original utilizando getImageData (un rectángulo)
  4. 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(); 

Respuesta

10

literatura no toman putImageData,

acaba de hacer un extra en tela de memoria con document.createElement para crear la máscara y se aplica que con un drawImage() y la función globalCompositeOperation (dependiendo del orden en que necesita elegir el modo correcto;

debo hacer something similar here la code is here (la mente la función CasparKleijne.Canvas.GFX.Composite)

+0

impresionante! ¡Funciona! Muchas gracias. –

+0

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. –

+0

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;) –