< Hosting Feliz Navidad y prospero año nuevo (o "no posteo nada más hasta el 2009") >

Generar un thumbnail cuadrado con PHP y GD

Muchas veces cuando subimos imagenes a una web, queremos también guardar un thumbnail para hacer un preview de las imágenes guardadas, pero no queda muy prolijo mostrar los thumbs de distintas dimensiones uno al lado del otro. Una solución es guardar los thumbs de la misma dimensión (cuadrados por ejemplo) tomando el centro de la imagen y cortando "lo que sobra". Hacer esto es muy fácil usando la librería GD de PHP, acá les dejo una función (traté de comentarla un poco porque no soy muy bueno documentando, :P):


function saveSquareThumb($file, $savePath, $thumbD=120){
		
  //Obtenemos la informacion de la imagen, el array info tendra los siguientes indices:
  // 0: ancho de la imagen
  // 1: alto de la imagen
  // mime: el mime_type de la imagen
  $info = getimagesize($file);

  //Dependiendo del mime type, creamos una imagen a partir del archivo original:
  switch($info['mime']){
    case 'image/jpeg':
      $image = imagecreatefromjpeg($file);
      break;
    case 'image/gif';
      $image = imagecreatefromgif($file);
      break;
    case 'image/png':
      $image = imagecreatefrompng($file);
      break;
  }

  //Si el ancho es igual al alto, la imagen ya es cuadrada, por lo que podemos ahorrarnos unos pasos:		
  if($info[0] == $info[1]){
    $xpos = 0;
    $ypos = 0;
  }
  //Si la imagen no es cuadrada, hay que hacer un par de averiguaciones:
  else{
    if($info[0] > $info[1]){ 
      //imagen horizontal
      $xpos = ceil(($info[0] - $info[1]) /2);
      $ypos = 0;
      $width  = $info[1];
      $height = $info[1];
    }else{ 
      //imagen vertical
      $ypos = ceil(($info[1] - $info[0]) /2);
      $xpos = 0;
      $width  = $info[0];
      $height = $info[0];
    }
  }
  //Creamos una nueva imagen cuadrada con las dimensiones que queremos:
  $image_new = imagecreatetruecolor($thumbD, $thumbD);
  $bgcolor = imagecolorallocate($image_new, 255, 255, 255);  
  imagefilledrectangle($image_new, 0, 0, $thumbD, $thumbD, $bgcolor);
  imagealphablending($image_new, true);
		
  //Copiamos la imagen original con las nuevas dimensiones
  imagecopyresampled($image_new, $image, 0, 0, $xpos, $ypos, $thumbD, $thumbD, $width, $height);
		
  //Guardamos la nueva imagen como jpg con una calidad del 85%
  imagejpeg($image_new, $savePath.'.jpg', 85);
}

Y eso es todo... hay un par de cositas que se pueden configurar mejor, como ser el archivo de salida, es muy sencillo agregarle una variable más para poder guardarlo en cualquier otro formato, pero yo necesitaba algo asi de básico, y me anda muy bien

Como dije arriba, traté de ponerle comentarios para masomenos explicar lo que hace la función, por ahí la única parte que no se entiende muy bien es la de los datos que seteamos si la imagen es vertical u horizontal, que trataré de explicar ahora...
Supongamos que tenemos una imagen horizontal, lo primero que hacemos es setear la posicion desde donde comenzaremos a copiar la imagen en x = (ancho - alto) /2; y = 0. Despues seteamos que el nuevo alto y el nuevo ancho sean iguales al alto original de la imagen (que es menor que el ancho, se acuerdan?).
De esta forma cuando cuando copiamos la imagen original a la nueva imagen obtendremos un cuadrado cuyo alto y ancho seran iguales al alto original de la imagen, tomando el centro de la imagen y descartando lo que sobra a los lados. No se entiende? Dicen que una imagen vale más que mil palabras:

Redimensión

Obviamente, cuando la imagen es vertical la lógica es la misma...
Espero les sirva!

Post escrito el 21 de Octubre de 2008, archivado en Desarrollo web  PHP 

21-10-2008, 14:05

Gino

Muy bueno loco, muy util y facil de usar, justo lo que me hacia falta!

21-11-2008, 21:45

neopablix

Hola amigo, realmente muy util el script.
Sin embargo, permitime corregirte un punto: cuando subis imagenes cuadradas, no crea bien el thumb (sale todo negro).
Le falta un par de lineas:
esta parte:
"if($info[0] == $info[1]){
$xpos = 0;
$ypos = 0;"

deberia ser asi:
"if($info[0] == $info[1]){
$xpos = 0;
$ypos = 0;
$width = $info[1];
$height = $info[1];"


Espero les sea util, ahi nos vemos...

25-11-2008, 12:22

Mariano

Gracias pablix por la aclaración. Es verdad, me olvidé de setear width y height para imagenes cuadradas :P

23-02-2009, 9:28

Hander

Hola Mariano,
Estoy tratando de usar tu script ya que es justo lo que andaba buscando, pero algo estoy haciendo mal, porque no me funciona.
Bueno, te adelanto que no tengo mucha idea de PHP. Dicho esto te explico lo que hago:

He puesto tu código en un nuevo archivo thumbs_cuadrados.php, y hago un include desde otro archivo php donde hay un campo para que el usuario suba una imagen. La imagen me la guarda (con el código que ya tenía) pero el thumb no me lo crea.
La llamada la hago así:
saveSquareThumb($dir.$_FILES['userfile']['name'], '../../thumbs/',120);
La ruta a la carpeta thumbs es la correcta y dicha carpeta tiene permisos 777.
¿Se te ocurre qué puedo estar haciendo mal?

23-02-2009, 9:35

Hander

Olvidé comentarte que por supuesto el servidor tiene la librería GD instalada (versión 2.0.28)

23-02-2009, 20:02

Hander

Hola de nuevo,
...bueno, ya me aclaré...
Comento por si le sirve a alguien.
La función la llamé asi:
saveSquareThumb($dir.$_FILES[\'userfile\'][\'name\'], \'../../thumbs/\'.$_FILES[\'userfile\'][\'name\'],120);
Es decir, estaba poniendo mal el segundo parámetro. Le estaba indicando la carpeta donde guardar los thumbs pero no qué nombre darle.

Además de esto me he encontrado más errores. Primero me creaba thumbs que no podía ver, porque tenían permisos 0600. Lo arreglé poniendo chmod($savePath, 0755); en la última linea.
Después, ya se me veían los thumbs, pero eran blancos...
Hasta que me di cuenta de que tienes una errata, la variable $fileIn debería ser $file.
Tampoco está bien escrito ImageFilledRectangle que sería imagefilledrectangle.
En fin, me he comido la cabeza más de lo esperado, pero el script anda de lujo.
Un saludo!

25-02-2009, 14:39

Mariano

Hola Hander! Gracias por tu comentario y por las aclaraciones (ya mismo corrijo el post). A veces pasa por escribir sin probar los scripts que le erro a alguna variable :P. Me alegro que te haya servido y que hayas solucionado los problemas.
Saludos!

Ultimos posts
Cerrado hasta nuevo aviso

¿Qué sentido tiene tener un blog para tenerlo abandonado?

Existe el antispam perfecto?

Creo que ya se la respuesta a esta pregunta...

Hosting bueno y barato

Por US$ 72 tenes PHP5, MySQL 5, dominios ilimitados y 4 .com gratis

Categorias

Lo más comentado

Auspiciantes

Contacto

Si querés enviarme comentarios, preguntas, sugerencias, saludos, propuestas (decentes o indecentes), insultos, piropos, spam o lo que se te ocurra podés hacerlo a través del formulario de contacto

Amigos

Por si te aburriste de este sitio, te dejo algunos para que conozcas: