¿Cómo recortar y redimensionar imágenes en PHP?

En esta entrada voy a hablar de un problema que he tenido que hacer frente en uno de los últimos trabajos, recortar y redimensionar imágenes en PHP.

Para recortar y redimensionar imágenes en PHP he hecho uso de la función imagecopyresampled nativa de PHP, la cual ya se usaba en el proyecto, además, por esta razón fue algo más difícil de entender al principio.

Para tratar de entender los conceptos y además ver qué iba sucediendo usé el log de errores de PHP, podéis leer más información de cómo usar y trabajar con el log de PHP aquí.

Por lo tanto voy a empezar a detallar la función para, más adelante, tratar de solucionar los problemas partir de ella. Así que, ahora sí, vamos allá con la explicación.

Función imagecopyresampled

Esta función PHP será la principal a la hora de recortar y redimensionar imágenes en PHP. (crop & resize images using PHP)

Recortar y redimensionar se hará a partir de esta función de PHP que, aunque es un poco liosa de usar al principio pero, una vez que se ha entendido será muy potente y será la que usaremos para editar imágenes desde PHP así como para recortarlas y redimensionarlas.

[Aquí tenéis el manual para la función en la página oficial de PHP en español.]

Los parámetros de la función según la documentación son los siguientes:

  • dst_image -> Recurso de tipo enlace a la imagen de destino.
  • src_image -> Recurso de tipo enlace a la imagen original.
  • dst_x -> Coordenada x del punto de destino.
  • dst_y -> Coordenada y del punto de destino.
  • src_x -> Coordenada x del punto de origen.
  • src_y -> Coordenada y del punto de origen.
  • dst_w -> Ancho del destino.
  • dst_h -> Alto del destino.
  • src_w -> Ancho original.
  • src_h -> Altura original.

Una vez que tenemos los parámetros de la función y tenemos más información es hora de ponerse manos a la obra.

Obtener los datos de la imagen original

Lo primero para redimensionar imágenes, es coger la imagen original y tenerla en memoria en php. Esto es fundamental, porque tener la imagen en memoria nos va a dar flexibilidad.

Para obtener los datos de una imagen, y así, poder crear una imagen desde un fichero de imagen es necesario tener la ruta al fichero $source. Además, es recomendable saber el tipo (content-type) de la imagen, que se puede obtener de diversas maneras. La más sencilla a través de la extensión del fichero. Una vez que tenemos el tipe ($type) y tenemos la ruta ($source) procedemos a obtener en memoria los datos de la imagen a tratar.

A partir de aquí, teniendo los datos de la imagen original en memoria, ya nos será posible realizar las modificaciones de la imagen, ya sea recortar la imagen, redimensionarla o ambas a la vez.

Eso se realiza con el siguiente código.

function createImageFromSource($source, $type)
{
    // JPG 
    if (preg_match('/jpg|jpeg/', $type))  $data = imagecreatefromjpeg($source);
    // PNG
    if (preg_match('/png/', $type))  $data = imagecreatefrompng($source);
    // GIF
    if (preg_match('/gif/', $type))  $data = imagecreatefromgif($source);
    return $data;
}

En la variable $data tendremos los datos de la imagen original, una vez que hemos usado la función.

Aquí tenemos la imagen que vamos a usar para esta prueba

Imagen de prueba para imagecopyresampled - Original

Imagen de prueba para imagecopyresampled. – Original

Redimensionar imágenes en PHP usando imagecopyresampled

Vamos a comenzar por redimensionar las imágenes, la tarea más sencilla y más fácil de entender.

El procedimiento es sencillo, simplemente consiste en generar una nueva imagen en memoria a partir de la original copiando la imagen anterior con las nuevas dimensiones.

Este pequeño trozo de código es una función util para hacer el resize o redimensionado de una imagen a partir de los datos de la imagen original.

function resizeImage($original_image_data, $original_width, $original_height, $new_width, $new_height)
{
    $dst_img = ImageCreateTrueColor($new_width, $new_height);
    imagecolortransparent($dst_img, imagecolorallocate($dst_img, 0, 0, 0));
    imagecopyresampled($dst_img, $original_image_data, 0, 0, 0, 0, $new_width, $new_height, $original_width, $original_height);
    return $dst_img;
}

Primero generamos una nueva imagen con las nuevas dimensiones, esto son las 2 primeras líneas de código de la función.

Ahora, una vez generada copiamos en esa nueva imagen a partir de la original con las dimensiones que deseamos.

Aunque es un poco lioso al principio, todo está en entender como funciona la función de PHP imagecopyresampled.

Detalle de la función de redimensionado

Básicamente los parámetros que le pasamos son los indicados en detalle a continuación:

  • 1. El destino.
  • 2. El origen de datos.
  • 3. El punto inicial X de la imagen destino (0).
  • 4. El punto inicial Y de la imagen destino (0).
  • 5. El punto inicial X donde empezar a copiar de la imagen original, al ser una copia completa será 0 en este caso.
  • 6. El punto inicial Y donde empezar a copiar de la imagen original, al ser una copia completa de la imagen será 0 en este caso.
  • 7. El punto final X de la imagen destino, en este caso las nuevas dimensiones (X) de la nueva imagen.
  • 8. El punto final Y de la imagen destino, en este caso las nuevas dimension (Y) de la nueva imagen.
  • 9. El area X a tomar de la imagen original a copiar en el destino. En este caso, todo el ancho al ser toda la imagen.
  • 10. El area Y a tomar de la imagen original a copiar en el destino. En este caso, todo el largo al ser toda la imagen.

Una vez aplicada la función en la variable de destino, tendremos los datos de la nueva imagen con las características deseadas.

Aquí tenemos un ejemplo de cómo ha quedado la imagen después de redimensionar.

Imagen de prueba para imagecopyresampled. - Redimensionada

Imagen de prueba para imagecopyresampled. – Redimensionada

Recortar imágenes en PHP usando imagecopyresampled

Una vez que tenemos los datos en memoria de la imagen original que queremos recortar. La manera más sencilla para recortarla, y lo que vamos a hacer, es generando otra imagen a partir de la original, pero tomando en cuenta los puntos de inicio y fin de recorte de la misma.

Usando el siguiente código se entenderá con más detalle.

function resizeImage($original_image_data, $original_width, $original_height, $new_width, $new_height)
{
    $dst_img = ImageCreateTrueColor($new_width, $new_height);
    imagecolortransparent($dst_img, imagecolorallocate($dst_img, 0, 0, 0));
    imagecopyresampled($dst_img, $original_image_data, 0, 0, 0, 0, $new_width, $new_height, $original_width, $original_height);
    return $dst_img;
}

Primero generamos una nueva imagen con las nuevas dimensiones, esto sonlas 2 primeras líneas de código de la función.

Aquí si son las mismas que la original, lo que haremos es agrandar el trozo de imagen a recortar, aunque esto ya dependerá de cómo que se quiera modificar la imagen.

Es un poco lioso al principio, pero todo está en entender como funciona la función de PHP imagecopyresampled.

Detalle de la función de recorte

Básicamente, lo que indicamos aquí es:

  • 1. El destino.
  • 2. El origen de datos.
  • 3. El punto inicial X de la imagen destino (0).
  • 4. El punto inicial Y de la imagen destino (0).
  • 5. El punto inicial X donde empezar a recortar de la imagen original. En este caso, se empezará a trazar la nueva imagen desde la posición 10 de la original.
  • 6. El punto inicial Y donde empezar a recortar de la imagen original. En este caso, se empezará a trazar la nueva imagen desde la posición 10 de la original.
  • 7. El punto final X de la imagen destino, en este caso las nuevas dimensiones (X) de la nueva imagen.
  • 8. El punto final Y de la imagen destino, en este caso las nuevas dimension (Y) de la nueva imagen.
  • 9. El area X a tomar de la imagen original a copiar en el destino. En este caso, la zona recortada será de 200 px en el eje X.
  • 10. El area Y a tomar de la imagen original a copiar en el destino. En este caso, la zona recortada será 200 px en el eje Y.

Una vez aplicada la función en la variable de destino, por fin tendremos los datos de la nueva imagen con las características deseadas.

Aquí tenemos a continuación como nos quedaría la imagen.

Imagen de prueba. Recortada y redimensionada.

Imagen de prueba para imagecopyresampled. – Recortada y redimensionada

Ejemplo de recorte básico

Aquí voy a usar otro pequeño trozo de código, en donde se explicará algo mejor la función de recorte y se verá más fácil.

$crop_image_data = imagecopyresampled($dst_img, $src_img, 0, 0, 10, 10, $new_width, $new_height, 200, 200);

En este caso, por ejemplo, lo que se ha producido es un recorte de una parte de la imagen original.

  • 1. Desde el punto 10 en el eje X hasta el punto 210
  • 2. Desde el punto 10 en el eje Y hasta el punto 210

Y esa zona recortada se añade en una imagen nueva, también en este caso al ser del mismo tamaño que la original lo que hemos hecho ha sido agrandar una porción de la imagen original.
Ya solo queda ir probando y jugando con las diferentes alternativas.

Generar datos binarios a partir de los datos de la imagen

Muy bien, esto ya sería nuestro último paso.

Una vez que tenemos generados los datos de la nueva imagen, ya sea recortada o redimensionada. Lo siguiente será generar los datos binarios a partir de los datos de la imagen.

Para ello podemos usar la siguiente función.

function generateBinaryDataFromImageData($image_data, $image_type)
{
    // Start with image buffer.
    ob_start();

    // Create image depending on image_type.
    if ( preg_match( '/jpg|jpeg/', $image_type ) )
        imagejpeg( $image_data );
    if ( preg_match( '/png/', $image_type ) )
        imagepng( $image_data );
    if ( preg_match( '/gif/', $image_type ) )
        imagegif( $image_data);

    // Get image binary data.
    $image_data = ob_get_clean();

    // Clean temp object.
    imagedestroy($image_data);

    return $image_data;
}

También aquí volvemos a necesitar el tipo de dato, y según el tipo de dato generar los datos binarios correspondientes.

Para ello usaremos un buffer de datos de PHP y una vez generados los datos binarios de la imagen y almacenados en una variable los destruiremos, todo ello antes de devolver los datos obtenidos para así evitar perdidas y fugas de memoria, además como vemos es una función muy simple y fácil de entender.

Con unas pocas funciones, hemos reducido la complejidad de la función imagecopyresampled de PHP también así podemos trabajar con nuestras propias funciones más sencillas y, en consecuencia, hacer un código más legible y entendible, obviamente esto nos va a permitir modificar imágenes de una manera más sencilla y simple.

En resumen, hemos visto que para recortar y redimensionar imágenes en PHP con una única función de PHP y un pequeño encapsulamiento y limpieza de código en funciones, se puede manejar de una manera sencilla, fácil y reutilizable.

Enlaces de interes

http://php.net/manual/es/function.error-log.php

http://php.net/manual/es/function.print-r.php

http://php.net/manual/es/function.imagecopyresampled.php

Comparte 🙂

Si te ha gustado el contenido de este artículo no te olvides de compartirlo ya que con eso me harías muy feliz. GRACIAS 😉

¿Y tú qué opinas?

Antes de participar en los comentarios, ten en cuenta que leeré personalmente cualquier cosa que escribas. Así que, por favor, mantén las formas y compórtate como una persona de bien.

  • (will not be published)

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>