Imágenes: Capas y máscaras
1 Capas con PGraphics
La clase PGraphics
funciona para crear “lienzos virtuales” o capas en los que podemos dibujar.
Estas capas se pueden comportar como imágenes PImage
: se dibujan con la función image( )
y se pueden modificar con métodos como .resize( )
o .filter( )
.
Por cada capa necesitamos una variable:
PGraphics capa;
En la función setup()
la inicializamos con un tamaño:
createGraphics( 640, 480 ); capa =
Para dibujar en ella podemos utilizar cualquier función de las que ya conocemos, pero ahora como métodos de la capa. Hay que preceder el dibujo con .beginDraw()
y terminarlo con .endDraw()
:
// dibuja en la capa:
beginDraw();
capa.background(0); // fondo negro
capa.fill(255); // relleno blanco
capa.ellipse( 320, 240, 100, 100);
capa.endDraw(); capa.
Posteriormente podemos dibujar la capa en la función draw()
con image( )
:
// dibuja la capa
image( capa, 0, 0);
1.1 Ejemplo: Figuras con blur
En este ejemplo dibujamos unos círculos en una capa, y luego utilizamos el método .filter( )
para aplicar un desenfoque.
// declara variable de tipo "PGraphics"
PGraphics capa1;void setup(){
size( 640, 480 );
// crea la capa
createGraphics(640, 480);
capa1 = // dibuja en la capa
beginDraw();
capa1.background( 0 );
capa1.fill( 255 );
capa1.ellipse(100, 100, 100, 100);
capa1.fill(0);
capa1.ellipse(100, 100, 80, 80);
capa1.fill(255);
capa1.ellipse(100, 100, 40, 40);
capa1.endDraw();
capa1.// podemos aplicar un filtro como si la capa fuera PImage
filter( BLUR, 3);
capa1.
}
void draw(){
// dibujamos la capa en el canvas como si fuera PImage
image( capa1, 0, 0);
}
2 Capas como Máscaras
Podemos utilizar las capas dibujadas con PGraphics
como máscaras del canal alpha de una imagen, aprovechando el método .mask( )
de PImage
.
La imagen o capa que utilicemos como máscara ha de estar en escala de grises, y se va a utilizar como canal alpha de la imagen enmascarada.
Los pixeles donde la máscara tenga un valor de 0 (color negro) se harán completamente transparente, los pixeles donde la máscara tenga un valor de 255 (color blanco) serán completamente opacos, y cualquier valor intermedio tendrá una transparencia correspondiente.
2.1 Ejemplos de máscaras
2.1.1 Máscara generada programáticamente
En este ejemplo usamos un ciclo for
para generar una máscara que consiste en franjas blancas y negras alternadas.
Esta máscara la aplicamos sobre la imagen original.
En el fondo se dibuja una copia de la imagen que fue obtenida y filtrada previamente.
// imagen original
PImage foto; // imagen invertida
PImage fotoInvertida; // capa
PGraphics capa1;
void setup() {
size( 640, 480 );
// crear "objeto" de tipo PImage
loadImage("trajinera.jpg");
foto = resize( width, height );
foto.
// copiar foto
get();
fotoInvertida = foto.filter( INVERT ); // invierte foto
fotoInvertida.
// crea capa para la máscara:
createGraphics( 640, 480);
capa1 =
// dibuja máscara:
beginDraw();
capa1.background(0);
capa1.fill(255);
capa1.// dibuja múltiples franjas rectangulares
for (int i=0; i<=640; i+=40) {
rect(i, 0, 20, 480);
capa1.
}endDraw();
capa1.
// enmascara la imagen
mask( capa1 );
foto.
}
void draw() {
background(255);
// dibuja la imagen invertida de fondo
image(fotoInvertida, 0, 0);
// dibuja la imagen enmascarada,
// sus áreas transparentes dejarán ver el fondo
image(foto, 0, 0);
// con esta función podemos ver el aspecto de la máscara
//image( capa1, 0, 0);
}
2.1.2 Máscara interactiva
Podemos aprovechar el ciclo de animación para redibujar la máscara en cada frame.
En este ejemplo usamos una estructura similar al anterior, con la diferencia de que la máscara se dibuja dentro de la función draw()
y los círculos en ella dependen de las variables mouseX
y mouseY
.
// foto original
PImage foto; // foto invertida
PImage fotoInvertida;
PGraphics capa1;
void setup(){
size( 640, 480 );
// crear "objeto" de tipo PImage
loadImage("trajinera.jpg");
foto = resize( width, height );
foto.
// copiar foto
get();
fotoInvertida = foto.filter( INVERT ); // invierte foto
fotoInvertida.
// crea capa para la máscara:
createGraphics( 640, 480);
capa1 =
}
void draw(){
// dibuja máscara en cada frame,
// utilizando coords mouseX, mouseY como centro de círculos
beginDraw();
capa1.background(0); // negro
capa1.fill(255); // blanco
capa1.ellipse(mouseX, mouseY, 300, 300);
capa1.fill(0); // negro
capa1.ellipse(mouseX, mouseY, 200, 200);
capa1.fill(255); // blanco
capa1.ellipse(mouseX, mouseY, 100, 100);
capa1.endDraw();
capa1.
// enmascara la imagen
mask( capa1 );
foto.
// dibuja la foto invertida de fondo
image(fotoInvertida, 0, 0);
// dibuja encima la foto original enmascarada
image(foto, 0, 0);
}
3 Capas para organizar el dibujo
En ocasiones queremos aprovechar el comportamiento de “dibujar sin borrar el fondo” en conjunto con otros comportamientos.
Dibujar en capas nos puede ayudar, como muestra este ejemplo.
Aquí se dibuja en una capa con un “pincel” obtenido como recorte de una imagen. Esta capa se dibuja encima de la imagen filtrada.
// Pincel a base de recorte
// El trayecto se dibuja sobre una "capa".
// Esto permite dibujar un fondo
PImage foto;
PImage recorte;
PGraphics capa;
void setup(){
size( 640, 480 );
// crear "objeto" de tipo PImage
loadImage("trajinera.jpg");
foto = resize( width, height );
foto.
// obtén un recorte de la foto a color
get(300, 300, 100, 100);
recorte = foto.
// filtra a la foto original (el recorte no se afecta)
filter( GRAY );
foto.
// crea la capa del tamaño del lienzo
createGraphics( 640, 480);
capa =
}
void draw(){
// actualiza la capa con el pincel
beginDraw();
capa.image( recorte, mouseX, mouseY);
capa.endDraw();
capa.
// dibuja la foto
image( foto, 0, 0);
// dibuja la capa encima
image( capa, 0, 0);
}