Comunidad de diseño web y desarrollo en internet online

Clase de PHP para crear Thumbnails de imágenes

Hace unos días tenía que hacer un sistema de administración donde en unos de sus módulos el cliente tenía que ser capaz de subir al servidor las imágenes que le correspondían a una serie de franquicias y luego en la web cuando seleccionara cada una de las franquicias debían aparecer estas imágenes con unas dimensiones determinadas. Habían dos tipos de imágenes, una era un Thumbnail que representaba a la franquicia y el resto eran imágenes que compondrían una galería.

Como el cliente tendría la libertad para subir cualquier imagen (sin importar sus dimensiones o peso) y no tenía experiencia con ningún software de edición de bitmaps, decidí que este trabajo debía realizarse desde el servidor.

Enseguida busqué en la web para ver si existían clases de edición de imágenes que utilizaran las funciones de php para redimensionar las mismas y me encontré con una enorme número de ellas, la mayoría trabajaba con las funciones natas de php, pero no tenían en cuenta el formato de la imagen y siempre guardaban un jpg (aunque el formato original no fuera este), esto provocaba en muchos casos que la imagen resultante fuera un cuadro negro (sobre todo con formatos gif).

Por otro lado ninguna de estas clases tenía un método que permitiera hacer un recorte de la imagen a las dimensiones que yo deseara sin variar las proporciones visuales de la imagen original, y esto me era imprescindible para generar automáticamente los thumbnails. Así que me di a la tarea de elaborar una clase que permitiera redimensionar las imágenes y crear los thumbnails sin variar la proporción visual de estas. El resultado fue el siguiente:

Fichero thumb.php

Código :

<?php
class thumb {

var $image;
var $type;
var $width;
var $height;

//---Método de leer la imagen
function loadImage($name) {

//---Tomar las dimensiones de la imagen
$info = getimagesize($name);

$this->width = $info[0];
$this->height = $info[1];
$this->type = $info[2];

//---Dependiendo del tipo de imagen crear una nueva imagen
switch($this->type){
case IMAGETYPE_JPEG:
$this->image = imagecreatefromjpeg($name);
break;
case IMAGETYPE_GIF:
$this->image = imagecreatefromgif($name);
break;
case IMAGETYPE_PNG:
$this->image = imagecreatefrompng($name);
break;
}
}

//---Método de guardar la imagen
function save($name, $quality = 100) {

//---Guardar la imagen en el tipo de archivo correcto
switch($this->type){
case IMAGETYPE_JPEG:
imagejpeg($this->image, $name, $quality);
break;
case IMAGETYPE_GIF:
imagegif($this->image, $name);
break;
case IMAGETYPE_PNG:
$pngquality = floor(($quality - 10) / 10);
imagepng($this->image, $name, $pngquality);
break;
}
}

//---Método de mostrar la imagen sin salvarla
function show() {

//---Mostrar la imagen dependiendo del tipo de archivo
switch($this->type){
case IMAGETYPE_JPEG:
imagejpeg($this->image);
break;
case IMAGETYPE_GIF:
imagegif($this->image);
break;
case IMAGETYPE_PNG:
imagepng($this->image);
break;
}
}

//---Método de redimensionar la imagen sin deformarla
function resize($value, $prop){

//---Determinar la propiedad a redimensionar y la propiedad opuesta
$prop_value = ($prop == 'width') ? $this->width : $this->height;
$prop_versus = ($prop == 'width') ? $this->height : $this->width;

//---Determinar el valor opuesto a la propiedad a redimensionar
$pcent = $value / $prop_value;
$value_versus = $prop_versus * $pcent;

//---Crear la imagen dependiendo de la propiedad a variar
$image = ($prop == 'width') ? imagecreatetruecolor($value, $value_versus) : imagecreatetruecolor($value_versus, $value);

//---Hacer una copia de la imagen dependiendo de la propiedad a variar
switch($prop){

case 'width':
imagecopyresampled($image, $this->image, 0, 0, 0, 0, $value, $value_versus, $this->width, $this->height);
break;

case 'height':
imagecopyresampled($image, $this->image, 0, 0, 0, 0, $value_versus, $value, $this->width, $this->height);
break;

}

//---Actualizar la imagen y sus dimensiones
$info = getimagesize($name);

$this->width = imagesx($image);
$this->height = imagesy($image);
$this->image = $image;

}

//---Método de extraer una sección de la imagen sin deformarla
function crop($cwidth, $cheight, $pos = 'center') {

//---Dependiendo del tamaño deseado redimensionar primero la imagen a uno de los valores
if($cwidth > $cheight){
$this->resize($cwidth, 'width');
}else{
$this->resize($cheight, 'height');
}

//---Crear la imagen tomando la porción del centro de la imagen redimensionada con las dimensiones deseadas
$image = imagecreatetruecolor($cwidth, $cheight);

switch($pos){

case 'center':
imagecopyresampled($image, $this->image, 0, 0, abs(($this->width - $cwidth) / 2), abs(($this->height - $cheight) / 2), $cwidth, $cheight, $cwidth, $cheight);
break;

case 'left':
imagecopyresampled($image, $this->image, 0, 0, 0, abs(($this->height - $cheight) / 2), $cwidth, $cheight, $cwidth, $cheight);
break;

case 'right':
imagecopyresampled($image, $this->image, 0, 0, $this->width - $cwidth, abs(($this->height - $cheight) / 2), $cwidth, $cheight, $cwidth, $cheight);
break;

case 'top':
imagecopyresampled($image, $this->image, 0, 0, abs(($this->width - $cwidth) / 2), 0, $cwidth, $cheight, $cwidth, $cheight);
break;

case 'bottom':
imagecopyresampled($image, $this->image, 0, 0, abs(($this->width - $cwidth) / 2), $this->height - $cheight, $cwidth, $cheight, $cwidth, $cheight);
break;

}

$this->image = $image;
}

}
?>


Los métodos de la clase son los siguientes:

Código :

// Lee la imagen desde la ruta especificada
loadImage($name:string)

// Guarda la imagen en la ruta especificada y con una calidad de 0 a 100 definida por el usuario (máxima calidad por defecto)
save($name:string, $quality:int = 100)

// Muestra la imagen en la página sin guardarla previamente
show()

// Redimensiona la imagen en ancho o alto manteniendo sus proporciones
// $prop puede tomar los valores de "width" o "height"
resize($value:int, $prop:string)

// Crea un thumbnail de la imagen con las medidas especificadas y manteniendo las proporciones visuales de la imagen intactas
// $pos puede tomar los valores de "left", "top", "right", "bottom" o "center"
crop($cwidth:int, $cheight:int, $pos:string)

Veamos un ejemplo concreto, aquí tenemos una imagen de 550 x 413 píxeles:



Vamos a crear una versión de la misma con un ancho de 100 píxeles:

fichero image_width_100.php

Código :

<?
include_once('thumb.php');
$mythumb = new thumb();
$mythumb->loadImage('http://img43.imageshack.us/img43/3022/finalfantasyn.jpg');
$mythumb->resize(100, 'width');
$mythumb->show();
?>

El resultado es el siguiente (en este momento estoy leyendo el php de arriba como una imagen) de la siguiente manera:

Código :

echo '<img src="image_width_100.php"/>';


Ejemplo de imagen con 100 píxeles de ancho

De la misma manera el siguiente link es la misma imagen con 100 píxeles de alto:

Ejemplo de imagen con 100 píxeles de alto

Y por último un crop de la imagen a 100 x 100 píxeles (igual a los avatares de aquí de la página):

Código :

<?
include_once('thumb.php');
$mythumb = new thumb();
$mythumb->loadImage('http://img43.imageshack.us/img43/3022/finalfantasyn.jpg');
// Como el rostro del personaje está a la derecha le especifico el parámetro $pos en "right"
// Si este valor es obviado el crop se hará del centro de la imagen
$mythumb->crop(100, 100, 'right');
$mythumb->show();
?>


Ejemplo de thumbnail a 100 x 100

Esta clase es muy util para los avatares de los foros, simpre se le advierte al usuario que debe subir una imagen de unas dimensiones específicas, pero los usuarios muchas veces no leen las reglas del foro o simplemente lo hacen por desconocimiento y entonces los avatares atentan contra el diseño del foro pues la imagen sale a su tamaño original. Podríamos utilizar esta clase para crear versiones de los thumbnails al tamaño que especifiquemos una vez que el usuario suba su imagen, de lo contrario hacer una versión al vuelo de esta imagen con las dimensiones que deseemos.

Espero que les sea de ayuda.

¿Sabes SQL? ¿No-SQL? Aprende MySQL, PostgreSQL, MongoDB, Redis y más con el Curso Profesional de Bases de Datos que empieza el martes, en vivo.

Publica tu comentario

o puedes...

¿Estás registrado en Cristalab y quieres
publicar tu URL y avatar?

¿No estás registrado aún pero quieres hacerlo antes de publicar tu comentario?

Registrate