[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>
- Incluye una lista de los sitios que pueden visualizar las imagenes
- 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
- Leyendo esta entrada se me ocurrió lo de modificar la imagen, en vez de motrar otra
- Documentación ModRewrite
- De aquí aprendí bastante
35 Comentarios | deja el tuyo



@cristian, diferente en que?
Que tienes bastantes subscriptores vía mail… yo creo que tengo 2 XD Y en mi caso la mayoría usa GReader
Y creo que tienes más subscriptores que yo, no recuerdo cuantos tengo
mira estoy desarolalando unproyecto no se si domines c# y agregar el boton de esacala de grises me esta fallando mira ya rompi la imagen y multiplique matrises pero nada mas no puedo sacar lo de la escala de grises si me pudieras ayudar no es q me lo agas pero si me pudieras dar una acesoria
Que tal, pues la verdad es que yo soy bastante principiante en php, sin embargo pues hice un agregado a tu script, un sistema de cache para evitar la sobre carga del servidor (a mi me pasaba luego de muchas ejecuciones continuas)
Verificalo y me cuentas si tengo algun error.
Joder, me suprimio el codigo… mandame un mail para hacerte llegar el codigo…
inteesante, de hecho es lo que estaba busando, ahora si queremos que las imagenes que carguen esten en un server de imagenes gratuitaos como imagehack o similar, solo debemos agregar la direccion de esa imagen, no??
saludos
Claro, tan simple como eso!
de mas agradecido!, ahora me queda ver que server uso!
saludos y gracias
bueno les dejo la consulta por ahi puede ser un tema del servidor… estoy probando esto en un directorios de enlaces hecho con phpld y agrego la siguiente linia al htacces
RewriteRule .*\.(gif|jpg|jpeg|png|bmp)$ http://img196.imageshack.us/img196/8088/enlaceblogdir6.gif [R,NC,L]
el tema es que en algunos sitios no me muestra nada y en otros me lo muestra en cualquier posición….
saludos
Hola, use tus funciones para redimensionar las imagenes antes de subirlas a la BD y quedó perfecto, gracias. Pero hay imagenes sobre 1600px en que da un error de memoria. Esta imagen pesa 396Kb y las dimensiones son 3000 x 2121.
Este es el error: Fatal error: Allowed memory size of 33554432 bytes exhausted (tried to allocate 413965 bytes)
Espero me puedas ayudar.
Hola andrés, debes modificar una de las opciones del archivo php.ini en el que indicas la máxima cantidad de RAM que puedes usar.
Un saludo!
Cristian, Gracias por contestar.
Modifiqué la memoria limite del php.ini y mejoró, me dejo subir la foto, pero ahora tengo otra foto y pereciera que tengo que agrandar mas y mas la memoria limite. Ya voy en 512M. Como puedo restringir que intenten subir estas imágenes.
Salu2.
Umm… OK, eso lo haces directamente desde PHP… en muchas partes se explica cómo hacerlo, por ejemplo:
http://www.maestrosdelweb.com/editorial/upphp/
Un saludo!
Hola Cristian.
Yo tambien uso $_FILES['archivo']['size']; para restringir el tamaño. Tengo imagenes que pesan 300k y no tengo problemas para subirlas y redimensionarlas, pero hay otras que pesan menos, pero que superan los 1600px donde aparece el error. Eso me ocurre justo en la linea donde ejecuto $im = imagecreatefromstring($bin_data);
En un foro decían que que se debe a la función descomprime la imagen para poder trabajar con ella….. no se que tan valido es eso…. pero ahora estoy tratando de manejar el error que aparece para que el usuario entienda lo que pasó. Sabes como se hace?
Salu2
uso la segunda opcion y me da error 500
Que bien explicado, se agradece mucho!!!!!