Creando un Editor de Imagen Usando CamanJS: Capas, Modos de Fusión y Eventos
Spanish (Español) translation by Rafael Chavarría (you can also view the original English article)
En el tutorial anterior, aprendiste cómo crear un editor de imagen usando CamanJS el cuál puede aplicar filtros básicos como contraste, brillo, y ruido a una imagen. CamanJS también tiene otros filtros integrados como Nostalgia, Pinhole, Sunrise, etc., los cuáles aplicamos directamente a la imagen.
En este tutorial, vamos a cubrir algunas características más avanzadas de la librería como Capas, Modos de Fusión y Eventos.
Capas en CamanJS
En el primer tutorial, solo trabajamos con una sola capa la cuál contenía nuestra imagen. Todos los filtros que aplicamos solo manipulaban esa capa principal. CamanJS te permite crear múltiples capas para que puedas editar tus imágenes de forma más sofisticada. Puedes crear capas anidadas. pero siempre serán aplicadas en su capa padre como una pila.
Siempre que creas una nueva capa y la aplicas en la capa padre, el modo de fusión usado por defecto será normal. Puedes crear una nueva capa en el lienzo usando el método newLayer(). Cuando creas una nueva capa, también puedes pasar una función callback que será útil si pretendes manipular la capa.
Esta función puede ser usada para muchas tareas como establecer el modo de fusión para la nueva capa usando el método setBlendingMode(). De manera similar, puedes controlar la opacidad de la nueva capa usando el método opacity().
Cualquier nueva capa que crees puede ser rellenada con un color sólido usando el método fillColor(). También puedes copiar los contenidos de la capa padre a la nueva capa usando el método copyParent(). Todos los filtros sobre los que aprendimos en el tutorial anterior pueden ser también aplicados en la nueva capa que estamos creando. Por ejemplo, puedes incrementar el brillo de la capa recién creada usando this.filter.brightness(10).
En vez de copiar el padre o rellenar la capa con un color sólido, también tienes la opción de cargar cualquier otra imagen en la capa y sobreponerla en el padre. Justo como la imagen principal, podrás aplicar diferentes filtros a la imagen sobrepuesta también.
En el siguiente código, hemos adjuntado un evento manejador de clic a tres botones que rellenarán la nueva capa con un color sólido, la capa padre, y una imagen sobrepuesta respectivamente.
1 |
$('#orange-btn').on('click', function (e) { |
2 |
Caman("#canvas", function () { |
3 |
this.newLayer(function () { |
4 |
this.opacity(50); |
5 |
this.fillColor('#ff9900'); |
6 |
});
|
7 |
this.render(); |
8 |
});
|
9 |
});
|
10 |
|
11 |
$('#parent-btn').on('click', function (e) { |
12 |
Caman("#canvas", function () { |
13 |
this.newLayer(function () { |
14 |
this.opacity(50); |
15 |
this.copyParent(); |
16 |
this.filter.brightness(20); |
17 |
});
|
18 |
this.render(); |
19 |
});
|
20 |
});
|
21 |
|
22 |
$('#overlay-btn').on('click', function (e) { |
23 |
var oImg = new Image(); |
24 |
oImg.src = "trees.png"; |
25 |
|
26 |
Caman("#canvas", function () { |
27 |
this.newLayer(function () { |
28 |
this.opacity(50); |
29 |
this.overlayImage(oImg); |
30 |
this.filter.brightness(20); |
31 |
});
|
32 |
this.render(); |
33 |
});
|
34 |
});
|
Modos de Fusión en CamanJS
En la sección anterior, mantuvimos la opacidad de cualquier nueva capa que agregamos al lienzo por encima de 100. Esto se hizo porque la nueva capa ocultaría completamente de otro modo la capa antigua. Cuando colocar una capa sobre otra, CamanJS te permite especificar un modo de fusión el cuál determina el resultado final después de la colocación. El modo de fusión es establecido a normal por defecto.
Esto significa que cualquier nueva capa que agregas sobre el lienzo hará a la capa de abajo invisible. La librería tiene diez modos de fusión en total. Estos son normal, multiply, screen, overlay, difference, addition, exclusion, softLight, exclusion, y darken.
Como mencioné anteriormente, el modo de fusión normal establece el color final igual al color de la nueva capa. El modo de fusión multiply determina el color final de un pixel multiplicando los canales individuales juntos y después dividiendo el resultado entre 255. Los modos de fusión difference y addition funcionan de manera similar, pero restan y suman los canales.
El modo de fusión darken establece el color final de un pixel para ser igual al valor más bajo de canales individuales de color. El modo de fusión lighten establece el color final de un pixel para ser igual al valor más alto de canales individuales de color. El moso de fusión exclusion es algo similar a difference, pero establece el contraste a un valor más bajo. En el caso del modo de fusión screen, el color final es obtenido invirtiendo los colores de cada capa, multiplicándolos, y después invirtiendo otra vez el resultado.
El modo de fusión overlay actúa como multiply si el color del fondo es más oscuro, y actúa como screen si el color de fondo es más claro.
Si quieres que los colores en diferentes capas interactúen de manera diferente, CamanJS también te permite definir tus propios modos de fusión. Cubriremos esto en el siguiente tutorial de la serie.
Aquí está el código JavaScript para aplicar diferentes modos de fusión sobre una imagen:
1 |
$('#multiply-btn').on('click', function (e) { |
2 |
hexColor = $("#hex-color").val(); |
3 |
Caman("#canvas", function () { |
4 |
this.revert(false); |
5 |
this.newLayer(function () { |
6 |
this.fillColor(hexColor); |
7 |
this.setBlendingMode('multiply'); |
8 |
});
|
9 |
this.render(); |
10 |
});
|
11 |
});
|
12 |
|
13 |
$('#screen-btn').on('click', function (e) { |
14 |
hexColor = $("#hex-color").val(); |
15 |
Caman("#canvas", function () { |
16 |
this.revert(false); |
17 |
this.newLayer(function () { |
18 |
this.fillColor(hexColor); |
19 |
this.setBlendingMode('screen'); |
20 |
});
|
21 |
this.render(); |
22 |
});
|
23 |
});
|
En el código de arriba, obtenemos el valor de color Hexadecimal desde un campo de texto. Este color es después aplicado sobre la nueva capa. Puedes escribir el código para aplicar otros modos de fusión de manera similar.
Trata de especificar un color de tu elección en el campo de texto, y después aplica cualquiera de los modos de fusión dando clic sobre el botón respectivo. He aplicado los modos de fusión sobre un colo sólido en el ejemplo, pero también puedes aplicarlos sobre una imagen sobrepuesta de la sección anterior.
Eventos en CamanJS
Si subiste cualquier imagen grande en el demo del primer tutorial o el segundo tutorial, porías haber notado que el resultado de cualquier filtro aplicado o modo de fusión se volvió evidente después de mucho tiempo.
Las imágenes grandes tienen muchos pixeles, y calcular el valor final de diferentes canales para cada pixel después de aplicar un modo de fusión específico puede consumir mucho tiempo. Por ejemplo, cuando aplicamos el modo de fusión multiply sobre una imagen con dimensiones 1920*1080, el dispositivo tendrá que realizar multiplicación y división arriba de 6 millones de veces.
En tales casos, puedes usar eventos para darles a los usuarios alguna indicación sobre el progreso de un filtro o modo de fusión. CamanJS tiene cinco diferentes eventos que pueden ser usados cómo ejecutar funciones callback específicas en diferentes etapas. Estos cinco eventos son processStart, processComplete, renderFinished, blockStarted, y blockFinished.
Los eventos processStart y processComplete son disparados después de que un solo filtro comienza o termina su proceso de generación. Cuando todos los filtros que especificaste han sido aplicados sobre una imagen, la librería dispara el evento renderFinished.
CamanJS divide imágenes grandes en bloques antes de comenzar a manipularlas. Los eventos blockStarted y blockFinished son disparados después de que bloques individuales de la imagen han sido procesados por la librería.
En nuestro ejemplo, solo estaremos usando los eventos processStart y renderFinished para informar a los usuarios sobre el progreso de nuestra operación de edición de imagen.
1 |
Caman.Event.listen("processStart", function (process) { |
2 |
$(".process-message").text('Applying ' + process.name); |
3 |
});
|
4 |
Caman.Event.listen("renderFinished", function () { |
5 |
$(".process-message").text("Done!"); |
6 |
});
|
Con los eventos processStart y processFinish, tienes acceso al nombre del proceso operando actualmente sobre la imagen. Los eventos blockStarted y blockFinished, por otro lado, te dan acceso a información como el número total de bloques, el bloque siendo procesado actualmente, y el número de bloques terminados.
Intenta dar clic a cualquier botón en el demo de abajo y verás el nombre del proceso manipulando actualmente la imagen en el área debajo del lienzo.
Ideas Finales
El primer tutorial de la serie te mostró cómo crear un editor básico de imagen con filtros integrados de la librería CamanJS. Este tutorial te mostró cómo trabajar con más de una capa y aplicar diferentes filtros y modos de fusión a cada capa de manera individual.
Ya que el proceso de edición de imagen puede tomar un tiempo para imágenes grandes, también aprendimos cómo indicar a los usuarios que el editor de imagen está procesando la imagen y no inactivo.
En el siguiente y último tutorial de la serie, aprenderás cómo crear tus propios modos de fusión y filtros en CamanJS. Si tienes cualquier pregunta relacionada a este tutorial, siéntete libre de hacérmelo saber en los comentarios.



