thumbnails en PHP

Crear thumbnails on-demand con PHP (y la libreria gd) es bastante fácil. Aquí un ejemplo del modo tradicional.


Modo tradicional.


archivo thumb.php:
<?php 

// vars form
$image = $_GET['image'];
$H = $_GET['H'];
$W = $_GET['W'];

// maz size (pixels)
$array_info = getImageSize("$image");
$ample = $array_info[0];
$alt = $array_info[1];

if ($alt < $H) {
       $hmax = $alt;
} else {
       $hmax = $H;
}
if ($ample < $W) {
       $anchura = $ample;
} else {
       $anchura = $W;
}

$datos = getimagesize($image);
if($datos[2]==1){ $img = imagecreatefromgif($image); }
if($datos[2]==2){ $img = imagecreatefromjpeg($image); }
if($datos[2]==3){ $img = imagecreatefrompng($image); }

$ratio = ($datos[0] / $anchura);
$altura = ($datos[1] / $ratio);

if($altura > $hmax) {
       $anchura2 = $hmax * $anchura / $altura;
       $altura = $hmax;
       $anchura = $anchura2;
}

$thumb = imagecreatetruecolor($anchura,$altura);
imagecopyresampled($thumb, $img, 0, 0, 0, 0, $anchura, $altura, $datos[0], $datos[1]);

if($datos[2]==1){
       header("Content-type: image/gif");
       imagegif($thumb, NULL, 70);
}
if($datos[2]==2){
       header("Content-type: image/jpeg");
       imagejpeg($thumb, NULL, 70);
}
if($datos[2]==3){
       header("Content-type: image/png");
       imagepng($thumb, NULL, 9);
}

imagedestroy($thumb);

?>


UTILIZACIÓN:
<!DOCTYPE html> 
<html>
<head>
       <meta charset="utf-8">
       <title>galeria</title>
</head>
<body>

<?php
print "<a href='img/01.jpg' target='_blank'>";
print "<img src=\"thumb.php?image=img/01.jpg&H=100&W=100\">";
print "</a>\n";


print "<a href='img/02.jpg' target='_blank'>";
print "<img src=\"thumb.php?image=img/02.jpg&H=100&W=100\">";
print "</a>\n";
?>

</body>
</html>




Problemas del modo tradicional.


Anonymous ha puesto de moda los ataques de denegación de servicio https://es.wikipedia.org/wiki/Ataque_de_denegaci%C3%B3n_de_servicio Básicamente realizados con cualquier script que sea capaz de realizar 20 o 30 peticiones por segundo a un servidor web por el puerto 80.

Para proteger un servidor web de esos ataques, existe distinto software. El más utilizado probablemente sea el módulo de apache mod-evasive (libapache2-mod-evasive), que es fácil de instalar y de configurar.

Básicamente, lo que hace mod-evasive es detectar un determinado número de peticiones, durante un determinado tiempo, que vengan de una misma IP. Por defecto el límite estaría en 10 peticiones por segundo de la misma IP (nadie hace 10 peticiones por segundo a un servidor web, salvo que tenga un tic nervioso en el dedo)

Pero ahora imaginemos que tenemos una galeria de imágenes en ese servidor web, y utilizamos el modo tradicional para mostrar on-demand los thumbnails (miniaturas) de las imágenes de nuestra galeria. Y hay 25 imágenes... maldición: 25 peticiones por segundo! (a thumb.php). El servidor web lo está considerando un ataque, y mod-evasive hace que me muestre una linda pantalla de ERROR: Exceded Resources, aparte de dejarme sin acceso al servidor durante un determinado tiempo (que pueden ser varios minutos...)

En el modo innovador que propongo, se hace una sola petición al servidor web, y el tiempo de respuesta y el consumo de recursos es parecido:




Modo innovador.


<!DOCTYPE html> 
<html>
<head>
       <meta charset="utf-8">
       <title>galeria</title>
</head>
<body>

<?php
function thumb($image, $H, $W) {

       // medidas máximas en pixels
       $array_info = getImageSize("$image");
       $ample = $array_info[0];
       $alt = $array_info[1];

       if ($alt < $H) {
              $hmax = $alt;
       } else {
              $hmax = $H;
       }

       if ($ample < $W) {
              $anchura = $ample;
       } else {
              $anchura = $W;
       }


       $datos = getimagesize("$image");
       if($datos[2]==2){
              $img = imagecreatefromjpeg("$image");
       }
       if($datos[2]==3){
              $img = imagecreatefrompng("$image");
       }

       $ratio = ($datos[0] / $anchura);
       $altura = ($datos[1] / $ratio);

       if($altura > $hmax) {
              $anchura2 = $hmax * $anchura / $altura;
              $altura = $hmax;
              $anchura = $anchura2;
       }


       $thumb = imagecreatetruecolor($anchura,$altura);
       imagecopyresampled($thumb, $img, 0, 0, 0, 0, $anchura, $altura, $datos[0], $datos[1]);


       ob_start();

       if($datos[2]==2){
              imagejpeg($thumb, NULL, 80);
       }
       if($datos[2]==3){
              imagejpeg($thumb, NULL, 80);
       }
       imagedestroy($thumb);

       $final_image = ob_get_contents();
       ob_end_clean();
       return $final_image;
}


// UTILIZACIÓN:
$final_image = thumb("img/01.jpg", 100, 100);
$output = base64_encode($final_image);

print "<a href=\"img/01.jpg\" target='_blank'>";
print "<img src=\"data:image/jpg;base64,${output}\">";
print "</a>\n";




$final_image = thumb("img/02.jpg", 100, 100);
$output = base64_encode($final_image);

print "<a href=\"img/02.jpg\" target='_blank'>";
print "<img src=\"data:image/jpg;base64,${output}\">";
print "</a>\n";
?>

</body>
</html>

Si tienes alguna idea mejor, la puedes publicar aquí.

 

01-05-2018,  21h. 12m.

peritroncho:
Vale tio, me has salvado la vida...

add comment

 

add comment

 

all blogs        help  
 
© 2017, Carles Bataller - Disseny web cucurella.net