En este fragmento de código y, siguiendo con el anterior fragmento de código ya publicado donde veíamos como podemos convertir una imagen a escala de grises, vamos a ver como podemos añadir una marca de agua con JavaScript. Lo enmarcamos dentro de los fragmentos dedicados al tratamiento digital de imágenes. Este fragmento resulta un poco más complicado debido a que tenemos que incrustar una imagen dentro de otra. El resultado que queremos obtener es el siguiente:
Como puedes comprobar las dos imágenes son de diferente tamaño y el logotipo o la marca es una imagen binaria (dos colores). El color negro se va a eliminar y el color blanco es el que vamos a tener en cuenta para hacer la marca de agua.
Respecto al código hay que tener en cuenta ciertas cosas a la hora de recorrer la imagen. Como quiero colocar la marca de agua en el centro hay que calcular la posición donde vamos a insertar la marca para ello calculamos el centro de la imagen original o la imagen donde queremos colocar la marca de agua. Se hace dividiendo por dos el ancho y el alto de la imagen. Obtenido el centro ya podemos calcular la posición X (columnas) e Y (filas) máximo y mínimo para recorrer la imagen original, lo podéis ver más claro en el código.
Para mezclar las dos imágenes se hace una simple media entre las componentes de color. Recuerda que cuando estamos tratando una imagen píxel a píxel, cada uno de ellos tiene cuatro componentes de color R (rojo), G (verde), B (azul) y A (transparencia). La transparencia no la trataremos en este fragmento así que no se tocará. Sumamos las componentes R de la imagen original y de la imagen marca de agua y la dividimos por 2, eso lo hacemos por cada componente y por cada píxel de la imagen. El resultado lo debemos asignar a la imagen original y ya tendríamos nuestra marca de agua incrustada en la imagen original, así de sencillo. A continuación podemos ver todo el código y el resultado de este fragmento.
See the Pen OyJevx by Luis (@delValle) on CodePen.
Si quieres descargarlo todo en un archivo lo puedes hacer con el siguiente código, guárdalo como un archivo HTML y lo puedes ejecutar en tu propia máquina.
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="https://code.jquery.com/jquery.min.js"></script>
<style>
#canvas1{border:1px solid #2980b9; background: red;}
#canvas2{border:1px solid #2980b9; display:none;}
#original{border:1px solid #2980b9;}
#logo{border:1px solid #2980b9;}
td{text-align: center;}
</style>
<script>
// Función inicial de jQuery
$(function(){
// Obtenemos el canvas
var canvas1 = document.getElementById("canvas1");
var ctx1 = canvas1.getContext("2d");
// Creamos un nuevo canvas
var canvas2 = document.getElementById("canvas2");
var ctx2 = canvas2.getContext("2d");
// Imagen original
var imageOriginal = new Image();
// Imagen marca de agua
var imageAgua = new Image();
//Método click sobre el botón
$("#convertir").click(function(){
// Siempre la marca de agua tiene que ser menor que la imagen original
if(imageOriginal.width < imageAgua.width ||
imageOriginal.height < imageAgua.height)
{
alert('Marca de agua menor que imagen original');
}
else
{
// Asignamos la misma altura y ancho de la imagen al canvas
ctx1.canvas.height = imageOriginal.height;
ctx1.canvas.width = imageOriginal.width;
// Dibujamos la imagen en el canvas
ctx1.drawImage(imageOriginal,0,0);
// Asignamos la misma altura y ancho de la imagen al canvas
ctx2.canvas.height = imageAgua.height;
ctx2.canvas.width = imageAgua.width;
// Dibujamos la imagen en el canvas
ctx2.drawImage(imageAgua,0,0);
// Obtenemos la matriz de información de la imagen original
var imgData1 = ctx1.getImageData(0,0,canvas1.width,canvas1.height);
var data1 = imgData1.data;
// Obtenemos la matriz de información de la imagen logo
var imgData2 = ctx2.getImageData(0,0,canvas2.width,canvas2.height);
var data2 = imgData2.data;
// Calculo de la posición central de la imagen
var centroXmin = Math.round((imageOriginal.width /2) - (imageAgua.width / 2));
var centroXmax = Math.round((imageOriginal.width /2) + (imageAgua.width / 2));
var centroYmin = Math.round((imageOriginal.height /2) - (imageAgua.height / 2));
var centroYmax = Math.round((imageOriginal.height /2) + (imageAgua.height / 2));
// Variable para almacenar posición
var posicion = 0;
var posicionLogo = 0;
// Recorremos las filas y las columnas de la imagen, píxel a píxel
for (var x = centroXmin; x < centroXmax; x++) {
for (var y = centroYmin; y < centroYmax; y++) {
// Obtenemos posición
posicion = 4 * (y * imageOriginal.width + x);
posicionLogo = 4 * ((y - centroYmin) * imageAgua.width + (x - centroXmin));
// No tenemos en cuenta el negro
if(data2[posicionLogo] >= 100 &&
data2[posicionLogo + 1] >= 100 &&
data2[posicionLogo + 2] >= 100)
{
data1[posicion] = (data2[posicionLogo] + data1[posicion])/2;
data1[posicion + 1] = (data2[posicionLogo + 1] + data1[posicion + 1])/2;
data1[posicion + 2] = (data2[posicionLogo + 2] + data1[posicion + 2])/2;
}
}
}
// Asignamos la imagen al Canvas
ctx1.putImageData(imgData1,0,0);
ctx2.putImageData(imgData2,0,0);
}
});
// Lectura de imagen OJO, esto puede dar error de acceso con imágenes protegidas
// Original
imageOriginal.crossOrigin = "anonymous";
imageOriginal.src = $('#original').attr('src');
// Marca de agua
imageAgua.crossOrigin = "anonymous";
imageAgua.src = $('#logo').attr('src');
});
</script>
</head>
<body>
<table>
<tbody>
<tr>
<td>
<image id="original" src="https://farm4.staticflickr.com/3223/2962074312_06fcfc0a06_m.jpg"></image>
</td>
<td>
<image id="logo" src="https://farm7.staticflickr.com/6058/6216328605_2d0c7b16be_q.jpg"></image>
</td>
</tr>
<tr>
<td colspan="2">
<button id="convertir">Aplicar marca de agua</button>
</td>
</tr>
<tr>
<td colspan="2">
<canvas id="canvas1" width=140 height=140></canvas>
<canvas id="canvas2" width=140 height=140></canvas>
</td>
</tr>
</tbody>
</table>
</body>
</html>


