Rotación automática de imágenes

Facebooktwittergoogle_pluslinkedinmailFacebooktwittergoogle_pluslinkedinmail

A menudo nos encontramos con que tenemos que preparar un formulario que le permita al usuario subir imágenes a nuestro sitio. Estas imágenes deberán quedar a disposición nuestra, o del propio usuario que las ha subido, o de otros usuarios de nuestra web para visualizarlas. Supongamos, por ejemplo, que creamos un portal inmobiliario donde el usuario sube imágenes de un inmueble que desea vender.

El problema aparece cuando esas imágenes han sido tomadas con una cámara digital, teléfono móvil, tablet, etc. Estos dispositivos incorporan a dichas imágenes lo que se conoce cómo información Exif. Se trata de un conjunto de metadatos que no se aprecian al visualizar la fotografía. Sin embargo, uno de los metadatos que se incluyen especifica una orientación concreta para la imagen. El resultado es que el usuario sube una imagen que concidera que es correcta y nuestra página la muestra rotada 90, 180 0 270 grados. Sin embargo, si visualizamos la imagen en nuestro sistema operativo, o con un programa de visiualización de imágenes, se muestra correctamente. ¿Que hacer en este caso?

EL PROBLEMA

Cómo hemos comentado, el problema es que uno de los datos Exif (cuyo nombre es, precisamente, Orientation) fuerza a que nuestra página nos muestre la imagen rotada. Pero hay otro problema. Ese parámetro no está presente en todas las imágenes, o no siempre tiene el mismo valor de orientación. Por lo tanto, lo que tenemos que hacer es detectar si ese parámetro está presente, y cual es su valor. Según dicho valor tendremos que sobrescribir la imagen con la orientación adecuada para que nuestra web la muestre correctamente.

LA SOLUCIÓN

Afortunadamente, PHP incluye una gran cantidad de funciones para manipulación de imágenes. Gracias a ellas, es posible contar con una clase que nos permite detectar la orientación que aparece en los metadatos de la imagen, y sobrescribir el fichero con la orientación adecuada. La clase se llama ExifCleaning y la hemos almacenado en un archivo llamado class.ExifCleaning.php, cuyo listado aparece a continuación:

EL PROCESO

La manera de emplear este recurso es la siguiente:

Parto de la base de que estás familiarizado con el proceso de subida de imágenes al servidor. En el formulario se incluyen campos de tipo file para que el usuario seleccione las imágenes que quiere subir. Estas llegan, como sabes, al servidor por medio de la matriz $_FILES. Una vez que se han empleado los datos de dicha matriz para comprobar que el archivo enviado sea de un tipo MIME acorde con imagenes (image/jpeg, image/gif, etc), así cómo que no se exceda el peso del archivo que establezcamos como límite, se almacena la imagen el el servidor con la función de PHP move_uploaded_file(), como se ve en el siguiente ejemplo:

move_uploaded_file($_FILES["nombre_de_campo_file"]["tmp_name"], $rutaDeDestino.$nombreDelArchivo);

Hasta aquí, todo normal. Si no estás familiarizado con la gestión básica de archivos enviados al servidor mediante un formulario, te sugiero que leas este artículo, que te sacará de dudas.

Ahora tenemos que añadir algo más al script que recibe el formulario con las imágenes. En primer lugar, al principio del archivo, incluiremos la sigiente instrucción:

include ("class.ExifCleaning.php");

Esta instrucción supone que el archivo de la clase se encuentra en la misma ruta que el script que procesa el formulario. Si no fuera así, deberíamos incluir la ruta adecuada, como es normal cuando se emplea include() o require().

A continuación debemos irnos a la línea de código que graba la imagen en el disco del servidor. Ya ssabes, la que incluye la instrucción move_uploaded_file(). Justo debajo deberemos incluir las siguientes instrucciones:

chmod($rutaDelArchivoDeImagen.$nombreDelArchivoDeImagen, 0755);
ExifCleaning::adjustImageOrientation($rutaDelArchivoDeImagen.$nombreDelArchivoDeImagen);

La primera modifica los permisos del archivo que contiene la imagen, para que podamos sobrescribirlo sin problemas. La segunda es la que hace uso de la clase que hemos visto en este artículo para determinar la orientación Exif de la imagen y, si procede, sobrescribirla, en el mismo fichero, correctamente orientada.

ATENCIÓN. Observa que la clase está diseñada para trabajar con imágenes en formato .jpg, ya que es como las cámaras digitales, teléfonos y otros dispositivos crean las fotografías.

La clase te la puedes descargar en este enlace. Es de uso libre y puedes incrporarla directamente a tus proyectos.

     

2 comentarios:

  1. hola muy articulo una pregunta
    en
    $rutaDelArchivoDeImagen.$nombreDelArchivoDeImagen

    se tiene que poner la ruta y archivo que lleva cada imagen por ejemplo

    $rutaDelArchivoDeImagen= “../../../images/portfolio/”.$name_file;
    $nombreDelArchivoDeImagen= $name_file;

    de antemano gracias
    saludos

    • Bueno. No estoy seguro de cual es tu duda, pero te diré que, con carácter general, cuando desde PHP referencias un archivo (sea una imagen, o cualquier otro), siempre debes referenciarlo con la ruta relativa a la ubicación de tu script. Si no especificas la ruta, el intérprete “entiende” que el archivo está en el mismo directorio que el script, y si no lo encuentra, puedes obtener un error, o un comportamiento inesperado.
      La solución es tener una estructura de archivos en tu sitio correctamente organizada, para saber siempre cual es la ruta relativa que buscas. Como alternativa, puedes usar la variable superglobal $_SERVER[“DOCUMENT_ROOT”], que te da la raíz del sitio, o la constante __FILE__, que contiene la ruta completa desde cualquier ubicación.

      Si la ubicación de archivos en tu proyecto es un problema, creo que encontrarás muy interesante el tema desarrollado en https://eldesvandejose.com/2018/01/01/autocarga-de-scripts-externos/.

      Espero haberte ayudado. Si necesitas algo más, no dejes de postearlo. Yo, o cualquiera de los campañeros, te responderemos.

      Un saludo.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *