gentoo linux, java, software libre y otras hierbas
sep, 06 2008 - 12:01 am

[Tutorial] Evitar hotlinking y sacarle provecho

El código PHP que nos permite modificar la imagen lo he dividido en funciones, que pondremos en el archivo (funciones.php). Veamos detalladamente cada función:

Transformar imagen a escala de grises [función blanco_negro()]

El funcionamiento de ésta función es algo complejo, pero podríamos decir que cambia píxel por píxel el color de la imagen, y devuelve su equivalente en blanco y negro:

function blanco_negro($nombre,$img){
	// Obtener las dimensiones de la imagen
	list($ancho, $altura) = getimagesize($nombre);
	// Definir nuestra fuente de imagen
	$fuente = $img;
	// Crear Canvas
	$imgblanconegro= imagecreate($ancho, $altura);
	//Crear una paleta de 256 colores
	for ($c=0;$c<256;$c++)
		$palette[$c] = imagecolorallocate($imgblanconegro,$c,$c,$c);
	//Funcion para modificar los colores
	function yiq($r,$g,$b){
		return (($r*0.299)+($g*0.587)+($b*0.114));
	}
	//Leer los colores originales pixel por pixel
	for ($y=0;$y<$altura;$y++)
		for ($x=0;$x<$ancho;$x++)
		{
			$rgb = imagecolorat($fuente,$x,$y);
			$r = ($rgb >> 16) & 0xFF;
			$g = ($rgb >> 8 ) & 0xFF;
			$b = $rgb & 0xFF;
			//Aqui es donde usamos yiq para cambiar los colores
			//y convertir la imagen a escala de grises
			$gs = yiq($r,$g,$b);
			imagesetpixel($imgblanconegro,$x,$y,$palette[$gs]);
		}
	// retornar la imagen creada working with
	return $imgblanconegro;
}

Redimensionar la imagen [función redimensionar()]

Esta función crea una nueva imagen a partir de la original, siempre y cuando la imagen sea más ancha o larga de 250px. Además, verifica la dimensión adecuada para la nueva imagen, es decir, si la imagen es más larga horizontalmente, crea una imagen de 250px de ancho y de alto la redimensiona de tal manera que guarde las proporciones, y viceversa.

function redimensionar($imagen){
	// Obtener el tamanio original
	$ancho = imagesx($imagen);
	$altura = imagesy($imagen);
	if($ancho > 250 || $altura > 250){
		if($ancho > $altura){
			//Asignar nuevo tamanio
			$nueva_anchura = 250;
			$av = 25000/$ancho;
			$nueva_altura = ($altura/100)*$av;
		}
		else{
			//Asignar nuevo tamanio
			$nueva_altura = 250;
			$av = 25000/$altura;
			$nueva_anchura = ($ancho/100)*$av;
		}
		// redimensionar
		$imagen_nueva = imagecreatetruecolor($nueva_anchura, $nueva_altura);
		imagecopyresampled($imagen_nueva, $imagen, 0, 0, 0, 0, $nueva_anchura, $nueva_altura, $ancho, $altura);
		return $imagen_nueva;
	}
}

Aplicar una marca de agua a la imagen [función marca_de_agua()]

Esta función crea un rectángulo negro en el centro de la imagen (imagefilledrectangle), y dentro de él inserta dos líneas de texto (imagestring), que nos permitirán indicarle al usuario que la imagen es nuestra:

function marca_de_agua($imagen, $texto, $texto2) {
	// Crear objetos de colores
	$blanco = imagecolorallocate($imagen, 255, 255, 255);
	$negro = imagecolorallocate($imagen, 0, 0, 0);

	// Aniadir el texto
	$ancho = 7.5*strlen($texto2);
	$primerX = (imagesx($imagen)-($ancho))/2;
	$altura = 40;
	$primerY = (imagesy($imagen)-($altura))/2;
	imagefilledrectangle  ( $imagen  , $primerX , $primerY  , $primerX + $ancho  , $primerY + $altura  , $negro  );
	imagestring($imagen, 3, $primerX+10, $primerY+3, $texto, $blanco);
	imagestring($imagen, 3, $primerX+10, $primerY+23, $texto2, $blanco);
	return $imagen;
}

Script que ejecuta las funciones [hotlink.php]

En el script hotlink.php, realiza lo siguiente:

  • Crear una variable con la dirección de la imagen que a procesar (línea 2)
  • Obtener la extensión de la imagen (líneas 3 y 4), y comprobar que sea realmente una imagen (línea 6), puesto que no queremos que nos carguen basura allí. Sería además conveniente que comprobaramos que la imagen es realmente nuestra, y que no se encuentra en otro servidor; esto no lo he implementado para no complicar las cosas.
  • Cargar el archivo de las funciones (línea 9)
  • Abrir la imagen (línea 11)
  • Transformar imagen a blanco y negro (línea 15)
  • Redimensionar la imagen (línea 17)
  • Poner una marca de agua (línea 19)
  • Generar la imagen JPG resultante (líneas 20 y 21)
<?php
$direccion_imagen = $_GET["i"];
$extension = strrchr($direccion_imagen, '.');
$extension = strtolower($extension);
//Verificar si es una imagen
if($extension == ".gif" || $extension == ".jpg" || $extension == ".jpeg" || $extension == ".png" || $extension == ".bmp")
{
	//Incluir las funciones
	include_once ("funciones.php");
	//Cargar imagen
	$imagen = abrir_imagen($direccion_imagen);
	if ($imagen === false) { die ('No se puede cargar la imagen'); }

	//Cambiar a blanco y negro
	$imagen = blanco_negro($direccion_imagen,$imagen);
	//Redimensionar la imagen
	$imagen = redimensionar($imagen);
	//Aplicar marca de agua
	$imagen = marca_de_agua($imagen, 'Visita casidiablo.net', 'Para ver la imagen correctamente');
	header('Content-type: image/jpeg');
	imagejpeg($imagen);
}
else echo "Que putas quieres?";
die();
?>

Para cargar el script cuando alguien intente hacernos hotlinking, debemos de configurar por supuesto nuestro .htaccess. A continuación, mi .htaccess con todos los ejemplos incluidos:

# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /wordpress/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /wordpress/index.php [L]
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^http://casidiablo.net$ [NC]
RewriteCond %{HTTP_REFERER} !^http://casidiablo.net/.*$ [NC]
RewriteCond %{HTTP_REFERER} !^http://www.casidiablo.net$ [NC]
RewriteCond %{HTTP_REFERER} !^http://www.casidiablo.net/.*$ [NC]
RewriteCond %{HTTP_REFERER} !^http://www.google.com/reader/view/.*$ [NC]
RewriteCond %{HTTP_REFERER} !^http://www.google.com/reader/m/view/.*$ [NC]
RewriteCond %{HTTP_REFERER} !^http://[^/.]\.feedburner\.com$ [NC]
RewriteCond %{HTTP_REFERER} !^http://feeds.feedburner.com/Casidiablo$ [NC]
RewriteRule .*\.(gif|jpg|jpeg|png|bmp)$ http://casidiablo.net/hotlink/hotlink.php?i=%{REQUEST_FILENAME} [R,NC,L]
</IfModule>
  1. Incluye una lista de los sitios que pueden visualizar las imagenes
  2. Y una redirección al script que modifica la imagen

Recuerda cambiar las URLs por las tuyas, tanto para la web, como para el feed y para el script PHP.

Enlaces y descargas

Descargar código fuente

Páginas de esta entrada: 1 2

39 Comentarios | deja el tuyo

4 enlaces entrantes

35 Comentarios en “[Tutorial] Evitar hotlinking y sacarle provecho”

  1. jackl007 dice:

    Sabes, es mejor quitarle el “blanco y negro”, he probado con imagenes superiores a 1920×1200 y la diferencia se nota, consume mas recursos y demora mas tiempo cambiar a blanco y negro solo por ahorrar unos cuantos kbs.
    PD: en la parte final falta que agreges el codigo de “abrir_imagen”, tube que descargar tu RAR para poder cojerlo.

    SALUDOS

  2. NeneLand dice:

    Buenas, muchisimas gracias por este tuto. Es sencillamente fantastico. Tan solo me queda una duda que me evitaria un monton de problemas. Necesitaria (si me puedes hacer el favor) que me indicases como podria impedir el hotlink tal y como mencionas en tu maravilloso post, pero permitiendo que si se acceda directamente (hotlink) a las imagenes que esten en una determinada carpeta (/images), por ejemplo. Mando una newsletter de vez en cuando y necesito que esas imaganes si sean accesibles, pero no las del resto de mi catalogo(/catalogo), por ejemplo. Mil y mil gracias.

  3. snake dice:

    Hola buen dato mi web estaba consumiendo casi 2gb menos de 10 mil paginas al dia.

    mi duda es que mi .htacces no esta como el tuyo:

    # BEGIN WordPress

    RewriteEngine On
    RewriteBase /wordpress/
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule . /wordpress/index.php [L]

    el mio dice:
    #redireccion temporal del feed hacia feedburner

    RewriteEngine on
    RewriteCond %{HTTP_USER_AGENT} !FeedBurner [NC]
    RewriteCond %{HTTP_USER_AGENT} !FeedValidator [NC]
    RewriteRule ^feed/?([_0-9a-z-]+)?/?$ http://feeds.feedburner.com/oneclickdd [R=302,NC,L]

    lo que hice fue agregarle antes de ifmodule> tu codigo para el hotlinking pero no se si deba completar la primera parte como el tuyo, me refiero a esto

    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule . /wordpress/index.php [L]

    saludos espero tu respuesta.

  4. snake dice:

    otra duda la imagen en blanco y negro tiene que estar alojada en mi host? porque si es asi igual estaria perdiendo ancho de banda aunque sea poco =S

¡Déjanos tu comentario!