Guía 91 – Reducción de imágenes manteniendo proporciones

El problema de la deformación al reducir el tamaño de una imagen, especialmente cuando la imagen es vertical o se ha tomado en un móvil, es general en PHPRunner. Esto ha ocurrido en todas las versiones y yo, al menos, lo he reportado pero , que yo sepa, nunca se ha resuelto.

En mis desarrollos en React, me tuve que enfrentar al problema de reducir las imágenes que tomaba del móvil y consultando en internet vi cómo se resolvía y así lo apliqué en mi desarrollo.

Se ha publicado en el foro de Xlinesoft este mismo problema y visto que a otros muchos desarrolladores tienen el mismo problema,  me he animado a hacer este ejercicio.

Objetivo

Hacer transformaciones del tamaño de las imágenes conservando su orientación y proporción, para después utilizar las mismas en PHPRunner o cualquier otra solución.

DEMO: https://fhumanes.com/resize/

Solución Técnica

Intentado que el ejemplo sea didáctico y que los desarrolladores puedan entenderlo para solucionar sus casos, he hecho el siguiente supuesto:

  • La imagen se almacena en el «filesystem» del server. Se crea una imagen «grande» ajustada a una tamaño y una miniatura «thumbnail» ajustada la tamaño que se indique.
  • En el ejemplo, sólo se permite y es obligatorio, una imagen por registro.
  • Los formatos de imágenes permitidas son PNG y JPEG.
  • En el ejemplo, el campo «imagen» se sabe si ha pasado el proceso de ajustes de las imágenes si ya dispone del el atributo de «thumbnail». Esta parte es ajustable a las necesidades que tengáis,
  • Los cambio se producen en el evento «Before Updated», tanto en la acción de «ADD» y de «EDIT».
  • Para la reutilización del mismo código, el algoritmo se pone en un fichero externo, que se ejecuta en los eventos indicados.

El fichero externo está en «MyCode/resize_image.php»

<?php
$dir = __DIR__.'/../'; // Path directory files

$size_image = 600;
$size_mini = 148;

// get information about uploaded files
$file_array = my_json_decode($values["imagen"]);
$file = $file_array[0];                   // In the example, only 1 file is allowed

if ($file['thumbnail'] ==  Null ) {        // If there is information is that the image has already become

    // handle single input with single file upload
    $uploadedFile = $file['name'];
    $dataFile = array();

    $dataFile['filename'] = $file['name'];
    $dataFile['type'] = $file['type'];

    $tempFile = tempnam(sys_get_temp_dir(), 'CO_'); // Create temporary file
    copy($dir.$uploadedFile, $tempFile)  ;          // Copy File

    // ++++++++++++++++++++++++++++++ Resize imagen +++++++++++++++++++++++++++++
    list($width, $height) = getimagesize($tempFile);

    // Get the image EXIF ​​data (if available)
    if ($dataFile['type'] == 'image/jpeg') { // JPEG
    $source = imagecreatefromjpeg($tempFile);
    } else {
    $source = imagecreatefrompng($tempFile);
    }
    $exif = exif_read_data($tempFile);

    // Verify if EXIF ​​data contains guidance information
    $orientation = $exif['Orientation'];
    if ( $orientation <> null) {
    // Rotate the image according to the EXIF ​​orientation
    switch ($orientation) {
    case 3:
    // Rotate 180 degrees
    $source = imagerotate($source, 180, 0);
    break;
    case 6:
    // Rotate 90 degrees in a schedule
    $source = imagerotate($source, 270, 0);
    // Invierto $width, $height
    $aux = $width;
    $width = $height;
    $height = $aux;
    break;
    case 8:
    // Rotate 90 degrees in anti -Horary sense
    $source = imagerotate($source, 90, 0);
    // Invierto $width, $height
    $aux = $width;
    $width = $height;
    $height = $aux;
    break;
    }
    }
    $thumbFile = tempnam(sys_get_temp_dir(), 'TH_'); // Crear fichero Temporal
    $origFile = tempnam(sys_get_temp_dir(), 'CO_'); // Crear fichero Temporal
    $percent1 = ($size_image)/$width; // Tamaño completo iamgen
    $newwidth1 = $width * $percent1;
    $newheight1 = $height * $percent1;
    $percent2 = ($size_mini)/$width; // Tamaño thumbnail imagen
    $newwidth2 = $width * $percent2;
    $newheight2 = $height * $percent2;
    $orig = imagecreatetruecolor($newwidth1, $newheight1);
    $thumb = imagecreatetruecolor($newwidth2, $newheight2);

    if ($dataFile['type'] == 'image/jpeg') { // JPEG
    imagecopyresized($orig, $source, 0, 0, 0, 0, $newwidth1, $newheight1, $width, $height);
    imagecopyresized($thumb, $source, 0, 0, 0, 0, $newwidth2, $newheight2, $width, $height);
    imagejpeg($orig,$origFile);
    imagejpeg($thumb,$thumbFile);
    } else { // PNG
    imagecopyresized($orig, $source, 0, 0, 0, 0, $newwidth1, $newheight1, $width, $height);
    imagecopyresized($thumb, $source, 0, 0, 0, 0, $newwidth2, $newheight2, $width, $height);
    imagepng($orig,$origFile);
    imagepng($thumb,$thumbFile);

    }
    unlink($tempFile); // Eliminamos temporal
    
    copy($origFile, $dir.$uploadedFile)  ;          // Copy File
    // Name File thumbnail
    $name_array = explode("/", $uploadedFile);
    $last_name = $name_array[sizeof($name_array)-1];
    $name_array = array_diff($name_array, array($last_name));
    $last_name = 'th_'.$last_name;
    $name_array[] = $last_name; 
    $name_thumbFile = implode('/',$name_array);
    copy($thumbFile, $dir.$name_thumbFile)  ;          // Copy File

    $file['size'] = filesize($origFile);
    $file['thumbnail']= $name_thumbFile;
    $ile['thumbnail_size']= filesize($dir.$name_thumbFile);
  
    // update values of the field that stores file names
    $file_array[0] = $file; 
    $values["imagen"] = my_json_encode($file_array);
    
    unlink($origFile); // Eliminamos temporal
    unlink($thumbFile); // Eliminamos temporal 
    }

Como siempre, os dejo el fuente para que lo descarguéis y probéis en vuestros PC’s.

Adjuntos

Archivo Tamaño de archivo Descargas
zip PHPRunner 10.7 + backup Base de Datos 34 KB 13

Blog personal para facilitar soporte gratuito a usuarios de React y PHPRunner