09 de Septiembre de 2010

Notas Espacio Programación

galería de imágenesvideo
AUTOR: Andrés Fernández
FECHA: 14/3/2009
LECTURAS:4077
Buscar Notas
volver
La potencia de la función imagefilltoborder

Esquinas redondeadas más simples

Veremos cómo redondear las esquinas de una imagen sin usar imágenes adicionales.
La técnica más común para redondear esquinas en PHP consiste en tomar imágenes prefabricadas y aplicarlas sobre la imagen original.

La verdad es que, aunque produce buenos resultados, prefiero algo más standalone y que no haga trabajar tanto al servidor.

Hay una función muy útil, perteneciente a la librería GD de PHP, que puede ayudarnos en esta tarea. Se trata de imagefilltoborder.

Vamos a citar el manual para ver qué hace exactamente:

Descripción
bool imagefilltoborder(resource $im,int $x,int $y,int $border,int $col)

imagefilltoborder() realiza un relleno hasta el color del borde que está definido por border . El punto de inicio para el relleno es x , y (arriba izquierda es 0,0) y la región se rellena con el color col .


Veamos una de las posibles aplicaciones de esta función:



El código utilizado es el siguiente:
<?php
if(isset($_GET['im'])){
    
header('Content-type:image/gif');
    
$img=imagecreatefromgif('mapaAmerica.gif');
    
$limit=imagecolorat($img317477);
    
$rojo=imagecolorallocate($img,255,0,0);
    if(isset(
$_GET['imageField_x']))
        
imagefilltoborder($img,$_GET['imageField_x'],$_GET['imageField_y'],$limit,$rojo);
    
imagegif($img);
    
imagedestroy($img);
    exit;
}
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Mapa</title>
<style>
*{margin:0}
h3{background-color:#000; color:#FFF; padding:3px; font-family:Verdana, Arial, Helvetica, sans-serif; font-size:10px;}
input{cursor:crosshair}
</style>
</head>
<body>
<h3>Hacer click sobre el mapa para colorearlo</h3>
<form id="form1" name="form1" method="get" action="<?php echo basename($_SERVER['PHP_SELF']) ?>">
  <input type="image" name="imageField" src="?im&<?php echo $_SERVER['QUERY_STRING'?>" />
</form>
</body>
</html>



Vemos que si la super global $_GET['im'] está definida, el archivo entrega la imagen procesada y sale (exit), y si no, muestra el formulario, que tiene un input type image cuyo atributo src es el mismo archivo pero con la variable get im siempre definida. El agregado de $_SERVER['QUERY_STRING'] es para recoger las coordenadas x e y que envía siempre un input type image cuando hacemos click sobre él, y que en este caso son usadas por imagefilltoborder para realizar el relleno.

¿Y qué tiene esto que ver con las esquinas redondeadas?

Es que básicamente podemos usar la misma técnica.
Los pasos serían:
1) Desde el punto 0,0 de nuestra imagen dibujamos una línea horizontal cuya medida sea igual al radio del borde que vamos a aplicar (imageline).
2) Hacemos lo mismo, pero esta vez con una línea vertical (imageline).
3) Dibujamos un arco que una los extremos separados de las líneas que acabamos de dibujar (imagearc).

Es importante que esos tres elementos tengan el mismo color, de manera que formen una figura cerrada de borde monocromo.

Veamos cómo sería en código:
<?php
header
('Content-type:image/gif');
$r=60;
$color='FFFFFF';
$img=imagecreatefromgif('1.gif');
$m=getimagesize('1.jpg');
$bg=imagecolorallocate($img,hexdec(substr($color,0,2)),hexdec(substr($color,2,2)),hexdec(substr($color,4,2)));
imageline($img,0,0,$r,0,$bg);
imageline($img,0,0,0,$r,$bg);
imagearc($img,$r,$r,$r*2+1,$r*2+1,180,270,$bg);
imagegif($img);
imagedestroy($img);
?>



Este sería el resultado de ese código:
ejemplo

Como vemos, ya tenemos lo mismo que en nuestro ejemplo del mapa: una superficie aislada por un borde, que podemos rellenar usando la función imagefilltoborder. Sólo nos queda definir un punto que se encuentre dentro de ella y rellenar a partir del mismo. El punto ubicado en las coordenadas 2,2 podría ser una buena opción:
<?php
header
('Content-type:image/gif');
$r=60;
$color='FFFFFF';
$img=imagecreatefromgif('1.gif');
$m=getimagesize('1.jpg');
$bg=imagecolorallocate($img,hexdec(substr($color,0,2)),hexdec(substr($color,2,2)),hexdec(substr($color,4,2)));
imageline($img,0,0,$r,0,$bg);
imageline($img,0,0,0,$r,$bg);
imagearc($img,$r,$r,$r*2+1,$r*2+1,180,270,$bg);
imagefilltoborder($img,2,2,$bg,$bg);
imagegif($img);
imagedestroy($img);
?>



Resultado:
ejemplo

Y listo, haciendo lo mismo con los bordes restantes y algunas modificaciones para que sea más reusable, podemos obtener algo como esto:
<?php
header
('Content-type:image/jpeg');
$r=!isset($_GET['r'])?20:$_GET['r'];
$color=!isset($_GET['color'])?'FFFFFF':$_GET['color'];
$img=imagecreatefromjpeg($_GET['img']);
$m=getimagesize($_GET['img']);
$bg=imagecolorallocate($img,hexdec(substr($color,0,2)),hexdec(substr($color,2,2)),hexdec(substr($color,4,2)));
/*sup-izq*/
if(!isset($_GET['si'])){
    
imageline($img,0,0,$r,0,$bg);
    
imageline($img,0,0,0,$r,$bg);
    
imagearc($img,$r,$r,$r*2+1,$r*2+1,180,270,$bg);
    
imagefilltoborder($img,2,2,$bg,$bg);
}
/*sup-izq*/
/*sup-der*/
if(!isset($_GET['sd'])){
    
imageline($img,$m[0],0,$m[0]-$r,0,$bg);
    
imageline($img,$m[0],0,$m[0],$r,$bg);
    
imagearc($img,$m[0]-$r,$r,$r*2+1,$r*2+1,270,360,$bg);
    
imagefilltoborder($img,$m[0]-2,2,$bg,$bg);
}
/*sup-der*/
/*abaj-izq*/
if(!isset($_GET['ai'])){
    
imageline($img,0,$m[1],0,$m[1]-$r,$bg);
    
imageline($img,0,$m[1],$r,$m[1],$bg);
    
imagearc($img,$r,$m[1]-$r,$r*2+1,$r*2+1,90,180,$bg);
    
imagefilltoborder($img,2,$m[1]-2,$bg,$bg);
}
/*abaj-izq*/
/*abaj-der*/
if(!isset($_GET['ad'])){
    
imageline($img,$m[0],$m[1],$m[0],$m[1]-$r,$bg);
    
imageline($img,$m[0]-$r,$m[1],$m[0],$m[1],$bg);
    
imagearc($img,$m[0]-$r,$m[1]-$r,$r*2+1,$r*2+1,0,90,$bg);
    
imagefilltoborder($img,$m[0]-2,$m[1]-2,$bg,$bg);
}
/*abaj-der*/
imagejpeg($img);
imagedestroy($img);
?>



Que podemos usar de esta manera para mostrar sólo algunas esquinas redondeadas y el radio por defecto:
<img width="500" src="roundCorner.php?img=38.jpg&amp;sd&amp;ai" />

Resultado:

ejemplo


O de esta otra para mostrar todas las esquinas redondeadas y otro radio:
<img src="roundCorner.php?img=39.jpg&amp;r=40" />

Resultado:

ejemplo


Y si quisiéramos aplicarlo sobre un fondo de color #CCCCCC, por ejemplo, podríamos usarlo asi:
<img alt="ejemplo" src="roundCorner.php?img=11.jpg&amp;r=40&amp;color=CCCCCC" />

Resultado:

ejemplo
Home - Quiénes Somos - Portfolio - Espacio Diseño - Espacio Programación - Capacitación - Contacto - RSS - XHTML 1.0