En este post voy a explicar y demostrar cómo se pueden poner marcas de agua con PHP utilizando las funciones de la librería GD.
Vamos a ver cómo poner la marca de agua en distintas posiciones (arriba a la izquierda, arriba a la derecha, centrada horizontal y verticalmente) y cómo modificar la opacidad de la marca de agua.
En la imagen de arriba se puede notar que he colocado una marca de agua de una “terminal” sobre una captura de código C (es sobre el post de generar números aleatorios con C).
He elegido estas dos imágenes porque el dueño soy yo, así que no pueden existir reclamaciones de derechos de autor y esas cosas que dan pereza.
Nota: recuerda que hace tiempo publiqué WaterPy, una aplicación similar pero escrita en Python.
A lo largo del tutorial explicaré las partes más importantes del código y ahorraré las repetitivas. Por ello es que he puesto todo el código actualizado en GitHub.
Primero debemos cargar la imagen; en este caso fueron imágenes PNG así que usamos la función llamada imagecreatefrompng
; si fuera jpeg sería imagecreatefromjpeg
. Ambas funciones reciben la ruta de la imagen,
Cuando tenemos una referencia al recurso de la imagen podemos obtener algunos datos de ella, por ejemplo la altura o anchura.
La función que realmente hace el trabajo de poner la marca de agua es imagecopy
, pues pone una imagen encima de otra en determinadas posiciones.
Veamos un ejemplo que coloca la marca de agua en la esquina superior izquierda, es decir, al “inicio” de la imagen:
<?php
/**
* Ejemplos de cómo poner marcas de agua con PHP y GD
*
* @author parzibyte
*/$rutaImagenOriginal = __DIR__ . "/codigo.png";
$rutaMarcaDeAgua = __DIR__ . "/marca.png";
$original = imagecreatefrompng($rutaImagenOriginal);
$marcaDeAgua = imagecreatefrompng($rutaMarcaDeAgua);
# En dónde poner la marca de agua sobre la original
$xOriginal = 0;
$yOriginal = 0;
# Desde dónde comenzar a cortar la marca de agua (si son 0, se comienza desde el inicio)
$xMarcaDeAgua = 0;
$yMarcaDeAgua = 0;
# Hasta dónde poner la marca de agua sobre la original
$alturaMarcaDeAgua = imagesy($marcaDeAgua) - $yMarcaDeAgua;
$anchuraMarcaDeAgua = imagesx($marcaDeAgua) - $xMarcaDeAgua;
imagecopy($original, $marcaDeAgua, $xOriginal, $yOriginal, $xMarcaDeAgua, $yMarcaDeAgua, $anchuraMarcaDeAgua, $alturaMarcaDeAgua);
# Imprimir y liberar recursos
header('Content-Type: image/png');
imagepng($original);
imagedestroy($original);
imagedestroy($marcaDeAgua);
Cuando llamamos a imagecopy
la imagen se copia, pero no se guarda ni se muestra. Para mostrarla directamente en el navegador enviamos un encabezado indicando el tipo de imagen y llamamos a imagepng
con un único argumento: el recurso de la imagen.
Para liberar los recursos tanto de la marca de agua como de la imagen a la que se le pone la marca de agua se llama a imagedestroy
.
Se supone que deberían liberarse automáticamente al salir del script pero no siempre se llamarán al final del script; por eso es una buena práctica liberar lo tomado.
Al principio es un poco difícil de comprender, pero yo te explico los argumentos en el orden que se mandan a imagecopy:
imagecreatefrom*
: Es la imagen sobre la cual se pone la marca de aguaimagesy
e imagesx
.Sabiendo lo anterior podemos jugar un poco con las matemáticas y las medidas de las imágenes para centrar completamente la marca de agua, tanto vertical como horizontalmente. El siguiente código ejemplifica cómo:
<?php
/**
* Ejemplos de cómo poner marcas de agua con PHP y GD
*
* @author parzibyte
*/$rutaImagenOriginal = __DIR__ . "/codigo.png";
$rutaMarcaDeAgua = __DIR__ . "/marca.png";
$original = imagecreatefrompng($rutaImagenOriginal);
$marcaDeAgua = imagecreatefrompng($rutaMarcaDeAgua);
# Como vamos a centrar necesitamos sacar antes las anchuras y alturas
$anchuraOriginal = imagesx($original);
$alturaOriginal = imagesy($original);
$alturaMarcaDeAgua = imagesy($marcaDeAgua);
$anchuraMarcaDeAgua = imagesx($marcaDeAgua);
# En dónde poner la marca de agua sobre la original
$centroHorizontalDeOriginal = floor($anchuraOriginal / 2);
$centroHorizontalDeMarcaDeAgua = floor($anchuraMarcaDeAgua / 2);
$centroVerticalDeOriginal = floor($alturaOriginal / 2);
$centroVerticalDeMarcaDeAgua = floor($alturaMarcaDeAgua / 2);
$centroHorizontal = $centroHorizontalDeOriginal - $centroHorizontalDeMarcaDeAgua;
$centroVertical = $centroVerticalDeOriginal - $centroVerticalDeMarcaDeAgua;
$xOriginal = $centroHorizontal;
$yOriginal = $centroVertical;
# Desde dónde comenzar a cortar la marca de agua (si son 0, se comienza desde el inicio)
$xMarcaDeAgua = 0;
$yMarcaDeAgua = 0;
# Hasta dónde poner la marca de agua sobre la original
$alturaMarcaDeAgua = $alturaMarcaDeAgua - $yMarcaDeAgua;
$anchuraMarcaDeAgua = $anchuraMarcaDeAgua - $xMarcaDeAgua;
imagecopy($original, $marcaDeAgua, $xOriginal, $yOriginal, $xMarcaDeAgua, $yMarcaDeAgua, $anchuraMarcaDeAgua, $alturaMarcaDeAgua);
# Imprimir y liberar recursos
header('Content-Type: image/png');
imagepng($original);
imagedestroy($original);
imagedestroy($marcaDeAgua);
Para centrar se saca el punto medio de la imagen y el punto medio de la marca de agua, después de eso se hace una resta y se redondea hacia abajo.
Si se desea guardar la imagen en el disco duro para su futuro procesamiento solamente se debe pasar un segundo parámetro a imagepng
: la ruta de la imagen (recuerda que el primer parámetro es el recurso de imagen)
<?php
$resultado = imagepng($original, "marcada.png");
Si queremos podemos cambiar la opacidad de la marca de agua para que se vea un poco transparente.
Para ello usamos la función imagecopymerge
que funciona exactamente igual que imagecopy
pero recibe un parámetro adicional: un entero que indica el porcentaje de opacidad.
<?php
# Usar imagecopymerge en lugar de imagecopy
# La diferencia es que al final se indica el porcentaje
imagecopymerge($original, $marcaDeAgua, $xOriginal, $yOriginal, $xMarcaDeAgua, $yMarcaDeAgua, $anchuraMarcaDeAgua, $alturaMarcaDeAgua, $porcentajeOpacidad);
Todo se comportará de la misma manera pero la marca de agua estará transparente. Entre menor sea el número, la marca de agua será más transparente.
Es totalmente posible colocar la marca de agua sobre la imagen en distintas posiciones, simplemente hay que llamar varias veces a imagecopy o imagecopymerge con distintos parámetros.
Al final, al llamar a imagepng
se obtendrá el resultado de todas las imágenes copiadas.
En el ejemplo utilizamos únicamente imágenes PNG pero se pueden utilizar otro tipo de imágenes, por ejemplo JPG, BMP, etcétera.
Para esto existen las funciones imagecreatefromjpeg y todas ellas que se pueden ver en el manual oficial.
Cuando trabajes con imágenes y las muestres directamente en el navegador recuerda establecer el encabezado a la forma correcta, por ejemplo image/jpeg.
De la misma manera, no siempre vas a llamar a imagepng
, puedes llamar a otras dependiendo del formato de tus imágenes.
Por si no lo leíste, puedes ver los ejemplos en GitHub y probar lo que hicimos en mi sitio web. Al inicio del post dejé los enlaces.
Puedes hacer que una imagen se envíe a través de un formulario y se ponga la marca de agua, por ejemplo. Las posibilidades son infinitas y todo depende de lo que necesidades.
Lee más sobre PHP aquí.
Hoy te voy a presentar un creador de credenciales que acabo de programar y que…
Ya te enseñé cómo convertir una aplicación web de Vue 3 en una PWA. Al…
En este artículo voy a documentar la arquitectura que yo utilizo al trabajar con WebAssembly…
En un artículo anterior te enseñé a crear un PWA. Al final, cualquier aplicación que…
Al usar Comlink para trabajar con los workers usando JavaScript me han aparecido algunos errores…
En este artículo te voy a enseñar cómo usar un "top level await" esperando a…
Esta web usa cookies.
Ver comentarios