Redimensionar y manipular imágenes en PHP (con ejemplos)

En mi tutorial anterior, discutimos la manipulación básica de imágenes usando la biblioteca PHP GD. En ese tutorial, hice una breve introducción a la biblioteca y le mostré cómo cargar imágenes de un archivo o crearlas desde cero en PHP. Después de eso, aprendimos cómo recortar, rotar, escalar y voltear una imagen usando GD. Cubrí el filtro de imagen () Función para aplicar diferentes filtros a los recursos de imagen cargados en el script. También mencioné algunas funciones útiles en GD como imagesx () y imaginario () para obtener el ancho y alto de la imagen cargada.

Al final de mi último tutorial de GD, aprendió a usar la biblioteca para automatizar tareas básicas como cambiar el tamaño de todas las imágenes en un directorio o aplicar filtros como escala de grises en ellas antes de guardar el resultado final. Si nunca antes ha usado la biblioteca GD de PHP, le sugiero que lea el artículo introductorio de GD antes de leer este..

En este tutorial, aprenderemos acerca de muchas otras funciones útiles en GD y cómo se pueden usar para automatizar más de nuestras tareas de manipulación de imágenes..

Manipulación de imágenes usando una matriz de convolución

A excepción de los píxeles en los bordes, cada píxel de una imagen está rodeado por otros ocho píxeles. Los efectos como el desenfoque o la detección de bordes se calculan para cada píxel según el valor de ese píxel y los valores de los píxeles circundantes. En la detección de bordes, por ejemplo, un cambio brusco en el color implica que hemos alcanzado el borde de algún objeto en la imagen. Por ejemplo, un cambio repentino de blanco a marrón en la imagen de abajo significará el límite de la taza y la mesa.

Una forma fácil de especificar este tipo de filtro es con lo que se llama una "matriz de convolución". GD suministra el imageconvolution ($ image, $ matrix, $ div, $ offset) Función para aplicar una matriz de convolución de 3x3 a un recurso de imagen. $ imagen

los $ matriz el parámetro es una matriz de tres matrices, cada una de las cuales contiene tres valores flotantes, es decir, Es una matriz de 3x3. El primer elemento de la primera matriz se multiplica por el valor del color del píxel superior izquierdo. De forma similar, el segundo elemento de la primera matriz se multiplica por el valor del color del píxel directamente sobre el píxel central. El color final del píxel se obtiene sumando el resultado de todas estas multiplicaciones y luego dividiéndolo por $ div Para la normalización. La normalización generalmente mantiene el valor del color final por debajo de 255.

Como hemos visto, la $ div El parámetro se utiliza como un divisor para que el resultado de la convolución normalice su valor. los $ offset El parámetro, por otro lado, se utiliza para especificar un valor de compensación para todos los colores. Verás cómo afecta el resultado final en los siguientes ejemplos..

Ejemplos de convolución

Aquí hay una lista de algunas matrices de convolución diferentes que hemos aplicado a la imagen de una taza en una tabla..

Caja de desenfoque

$ box_blur = array ([1, 1, 1], [1, 1, 1], [1, 1, 1]); imageconvolution ($ im_php, $ box_blur, 9, 0);

El desenfoque de caja funciona simplemente promediando cada píxel con sus vecinos. Establecemos el valor del divisor en 9 porque la suma de todos los elementos en las tres matrices es 9.

Afilar 

$ sharpen = array ([0, -1, 0], [-1, 5, -1], [0, -1, 0]); imageconvolution ($ im_php, $ sharpen, 1, 0); 

Sharpen funciona exagerando las diferencias entre cada píxel y sus vecinos. Esto hace que los bordes sean un poco más claros. En el caso de Sharpen, el divisor sigue siendo 1 porque la suma de todos los elementos en las tres matrices es 1. 

Realzar

$ emboss = array ([- 2, -1, 0], [-1, 1, 1], [0, 1, 2]); imageconvolution ($ im_php, $ emboss, 1, 0);

La matriz de relieve es similar a la matriz de nitidez, excepto que los valores son negativos en la parte superior izquierda y positivos en la parte inferior derecha; eso es lo que crea el efecto de relieve. La suma de todos los elementos en el caso de la matriz de convolución de relieve es 1, por lo que no debemos preocuparnos por la normalización o el desplazamiento del color..

Detección de bordes

$ edge_detect = array ([- 1, -1, -1], [-1, 8, -1], [-1, -1, -1]); imageconvolution ($ im_php, $ edge_detect, 1, 0); imageconvolution ($ im_php, $ edge_detect, 1, 255); 

La detección de bordes es similar a la nitidez, pero el efecto es aún más fuerte. Además, el valor original de la imagen no tiene más peso que los vecinos, lo que significa que solo nos preocupamos por los bordes, no por las áreas de colores sólidos originales.. 

Con la detección de bordes, la suma de todos los elementos de la matriz es 0. Esto significa que la imagen que obtendremos será mayormente negra a menos que haya un cambio agudo en el color, que generalmente ocurre en los bordes de los objetos. La imagen en su mayor parte negra se puede convertir en blanco configurando el parámetro de compensación en 255.

La siguiente imagen muestra el resultado de todas estas matrices de convolución..

Funciones de copia de imagen

PHP GD tiene muchas funciones para copiar parte de una imagen y luego redimensionarla o fusionarla. Al usar estas funciones, es importante recordar que PHP considera el origen de la esquina superior izquierda de un recurso de imagen. Un positivo X valor te llevará a la derecha de la imagen, y un positivo y el valor te llevará más abajo.

La más simple de estas funciones es imagecopy ($ dst_im, $ src_im, $ dst_x, $ dst_y, $ src_x, $ src_y, $ src_w, $ src_h). Copiará la imagen de origen en una imagen de destino. los $ dst_x y $ dst_y los parámetros determinan la esquina superior izquierda, donde se pegará la imagen copiada. los $ src_x, $ src_y, $ src_w, y $ src_h los parámetros determinan la parte rectangular de la imagen de origen, que se copiará al destino.

Puede utilizar esta función para recortar imágenes creando una imagen desde cero utilizando imagecreatetruecolor () y copiando el rectángulo de recorte de la imagen de origen en él. También puede usarlo para agregar marcas de agua en las imágenes, pero debe recordar que con este método, el tamaño de la marca de agua no se puede cambiar de acuerdo con el tamaño de nuestras imágenes..

Una solución a este problema es usar el imagecopyresized ($ dst_im, $ src_im, $ dst_x, $ dst_y, $ src_x, $ src_y, $ dst_w, $ dst_h, $ src_w, $ src_h) función. Acepta todos los parámetros de imagecopy () y dos parámetros adicionales para determinar el tamaño del área de destino donde se copiará la imagen de origen.

los imagecopyresized () La función no es perfecta, ya que no escala la imagen hacia arriba y hacia abajo muy bien. Sin embargo, puede obtener un mejor tamaño de calidad utilizando el imagecopyresampled () Función, que acepta todos los mismos parámetros..

Copiar Con Transparencia

Hay dos funciones más relacionadas con la copia de imágenes que te serán muy útiles: imagecopymerge () y imagecopymergegray ().

La función imagecopymerge ($ dst_im, $ src_im, $ dst_x, $ dst_y, $ src_x, $ src_y, $ src_w, $ src_h, $ pct) es parecido a imagecopy (), donde el adicional $ pct El parámetro determina la transparencia de la imagen copiada. Un valor de 0 significa que no hay transparencia, y un valor de 100 significa transparencia completa. Esto será de gran ayuda cuando no quiera ocultar completamente el contenido de la imagen principal detrás de su marca de agua..

los imagecopymergegray () La función, por otro lado, utiliza el último parámetro para convertir la imagen de origen a escala de grises. Si se establece en 0, la imagen de origen perderá todo su color. Si se establece en 100, la imagen de origen no se verá afectada.

Ejemplo de copia de imagen

El siguiente ejemplo usa el imagecopy () Función para convertir la mitad derecha de una imagen en su negativo. Ya hemos discutido otras funciones como filtro de imagen () y imagescale () utilizado en este fragmento de código en el tutorial anterior.

$ im_php = imagecreatefromjpeg ('fish-mosaic.jpg'); $ im_php = imagescale ($ im_php, 800); $ im_php_inv = imagescale ($ im_php, 800); $ im_width = imagesx ($ im_php); $ im_height = imagesy ($ im_php); filtro de imagen ($ im_php_inv, IMG_FILTER_NEGATE); imagecopy ($ im_php, $ im_php_inv, $ im_width / 2, 0, $ im_width / 2, 0, $ im_width / 2, $ im_height); $ new_name = 'fish-mosaic-half-negate.jpg'; imagejpeg ($ im_php, $ new_name);

Aquí, creamos dos copias de la imagen original, cada una de las cuales se ha reducido a 800 píxeles de ancho. Después de eso, usamos el filtro de imagen () función para crear un negativo de la $ img_php_inv recurso de imagen La mitad derecha de esta imagen negativa se copia en la imagen original usando la imagecopy () función.

Este fue un uso muy básico de la imagecopy () función. Puedes ver los resultados a continuación. También puede dividir la imagen en secciones o bandas más pequeñas para crear efectos de imagen más interesantes. Usaremos el imagecopymergegray () Funciona en el fragmento de código a continuación para crear muchas más franjas en la imagen original de Fish.

$ im_php = imagecreatefromjpeg ('fish-mosaic.jpg'); $ im_php = imagescale ($ im_php, 800); $ im_php_bw = imagescale ($ im_php, 800); $ im_width = imagesx ($ im_php); $ im_height = imagesy ($ im_php); $ rayas = 200; para ($ i = 0; $ i < $stripes; $i++)  if($i%2 == 0)  imagecopymergegray($im_php, $im_php_bw, $i*$im_width/$stripes, 0, $i*$im_width/$stripes, 0, $im_width/$stripes, $im_height, 0);  else  imagecopymergegray($im_php, $im_php_bw, $i*$im_width/$stripes, 0, $i*$im_width/$stripes, 0, $im_width/$stripes, $im_height, 100);   imagefilter($im_php, IMG_FILTER_CONTRAST, -255); imagefilter($im_php, IMG_FILTER_COLORIZE, 250, 0, 0, 100); $new_name = 'fish-mosaic-stripes.jpg'; imagejpeg($im_php, $new_name);

El ejemplo del código anterior utiliza una estrategia similar a la del ejemplo anterior, pero esta vez hemos dividido la imagen en franjas más pequeñas, que se convierten en escala de grises o se mantienen sin cambios según el valor de la variable $ i. Después de completar todas las operaciones de combinación de copia, aplicamos dos filtros en la imagen para que las franjas se destaquen.

La siguiente imagen muestra el resultado final de estas dos funciones junto con diferentes filtros de imagen.

Incrustación de marcas de agua u otra información en imágenes

Algunas organizaciones agregan marcas de agua a sus imágenes para dejar claro que son dueños de la imagen. También ayuda con el reconocimiento de la marca y desalienta a otras personas a copiar las imágenes descaradamente. Gracias a PHP GD, las imágenes de marca de agua son una tarea sencilla.

$ im_php = imagecreatefromjpeg ('waterfall.jpg'); $ watermark = imagecreatefrompng ('watermark.png'); $ im_width = imagesx ($ im_php); $ im_height = imagesy ($ im_php); $ watermark = imagescale ($ watermark, $ im_width / 5); $ wt_width = imagesx ($ watermark); $ wt_height = imagesy ($ watermark); imagecopy ($ im_php, $ watermark, 0.95 * $ im_width - $ wt_width, 0.95 * $ im_height - $ wt_height, 0, 0, $ wt_width, $ wt_height); $ new_name = 'waterfall-watermark.jpg'; imagejpeg ($ im_php, $ new_name);

En el fragmento de código anterior, hemos creado dos recursos de imagen diferentes utilizando imagecreatefromjpeg () para la imagen principal y imagecreatefrompng () para la marca de agua respectivamente. Determinamos el ancho y el alto de la imagen principal usando el imagesx () y imaginario () funciones.

No todas las imágenes que desea incluir en la marca de agua tendrán las mismas dimensiones. Si no cambia el tamaño de la marca de agua según las dimensiones de la imagen principal, puede parecer extraño. Por ejemplo, una marca de agua de 200px puede verse bien en una imagen de 1000px, pero será demasiado grande para una imagen de 600px de ancho, y puede parecer demasiado pequeña en una imagen de 2400px de ancho.

Por lo tanto, utilizamos el imagescale () función para mantener siempre la marca de agua en un quinto del ancho de la imagen original. Entonces usamos el imagecopy () Función para colocar la marca de agua en la ubicación correcta. Aquí está el resultado final del fragmento de código anterior.

Además de las marcas de agua, también puede agregar otra información como el lugar donde se tomó la fotografía o la hora en que se tomó la fotografía..

Pensamientos finales

Después de cubrir los conceptos básicos de la manipulación de imágenes en nuestro tutorial anterior, aprendimos sobre algunas otras funciones útiles en la biblioteca de GD. La primera parte del tutorial trató cómo podemos manipular imágenes en PHP usando la matriz de convolución. También mostré algunos ejemplos de la operación de matriz de convolución para ayudarlo a comprender cómo PHP llega a los valores de color de diferentes píxeles..

La segunda parte del tutorial explica cómo copiar y / o redimensionar parte de una imagen para pegarla en otro lugar. Esto es útil cuando queremos agregar algo a una imagen como una marca de agua o una marca de tiempo.

Intenta usar todas estas funciones para crear algunos efectos de imagen interesantes.!