Sentido Web

Referencias y explicaciones sobre desarrollo web, PHP, Ajax, XHTML, MySQL ...
11Apr
2006
Comments Off

Laboratorio: Recorta imágenes dinámicamente con PHP y HTML

En muchos sitios web de almacenamiento de imágenes se nos permite retocar las imágenes. Hoy vamos a explicar como recortar una imagen directamente desde una página web. crop.png Para ello tenemos que crearnos una página web que nos permita seleccionar la zona de la imagen que queremos recortar y de un script PHP que usando la librería GD recortará la imagen y la devolverá en formato PNG.

Primero es crear la página web que muestra la imagen y permite recortarla. Constará de una capa que contiene la imagen y de otra capa (span) que se usará para crear el marco de selección. Bueno, también hay una capa que mostrará la imagen resultante, pero esto no es necesario, solo es para mostrar el resultado en la misma página.

El HTML necesario para contener la imagen es el siguiente:

<div class="contenedor"
onclick="posicionaMarco(event)"
onmousemove="despliegaMarco(event)">
<img src="foto.jpg" alt="Foto" />
<span id="marco"></span>
</div>

La capa contenedor tendrá dos eventos que serán controlados:

  • onclick: cuando se pincha en la imagen se empecerá/finalizará la selección de la zona de la imagen que queremos recortar.
  • onmousemove: mientras se mueva el ratón por la imagen se creará el marco que indica que zona de la imagen se está seleccionando. En este caso, para no complicar la explicación del efecto, obligamos a que la selección se haga de izquierda-derecha y de arriba-abajo.

Los estilos solo hay que destacar que la capa contenedora debe tener el mismo tamaño que la imagen para evitar seleccionar más de la cuenta y que luego falle el script PHP, y que la capa marco debe tener el borde visible, en este caso sólido, rojizo y de 2 píxeles de grosor.

Cuando pinchamos en la imagen almacenamos la posición x e y del ratón, ya que será la esquina superior izquierda y luego inicializar los valores del marco.

var _IE_ = navigator.userAgent.indexOf("MSIE") != -1; // Si es IE
var inicio = false;
var xini = 0;
var yini = 0;
var xfin = 0;
var yfin = 0;
function posicionaMarco(e) {
inicio = !inicio;
var marco = document.getElementById("marco");
if (inicio) {
marco.style.display = "block";
// En IE y Opera se usa otra propiedad del evento
if (_IE_) {
xini = e.offsetX;
yini = e.offsetY;
} else {
xini = e.layerX;
yini = e.layerY;
}
marco.style.left = xini+"px";
marco.style.top = yini+"px";
marco.style.width = "0px";
marco.style.height = "0px";
}
}

Cuando se mueve el ratón por la superficie de la imagen (realmente de la capa), almacenamos la esquina inferior derecha del marco y modificamos el ancho y alto.

function despliegaMarco(e) {
if (inicio) {
var marco = document.getElementById("marco");
// En IE y Opera se usa otra propiedad del evento
// El 7 es para evitar que el ratón se solape con el marco y nos dé problemas
if (_IE_) {
xfin = e.offsetX-7;
yfin = e.offsetY-7;
} else {
xfin = e.layerX-7;
yfin = e.layerY-7;
}
// El 5 es para que haya un tamaño mínimo
if (xfin > xini+5) {
marco.style.width = (xfin-xini)+"px";
}
if (yfin > yini+5) {
marco.style.height = (yfin-yini)+"px";
}
}
}

Ya tenemos el HTML que nos permite seleccionar la zona de la imagen, ahora solo hace falta el script PHP. El funcionamiento es sencillo, carga la imagen, crea una imagen nueva con el tamaño final que debe tener y copiamos la zona que queremos recortar de la imagen en la nueva imagen. Por último devolvemos la imagen nueva.

<?php
// Abre la imagen
$fichero = getcwd()."/".$_GET["img"];
if (preg_match('/.png$/', $fichero)) {
$img = imagecreatefrompng($fichero);
} else if (preg_match('/.gif$/', $fichero)) {
$img = imagecreatefromgif($fichero);
} else if (preg_match('/.jpg$/', $fichero)) {
$img = imagecreatefromjpeg($fichero);
}
$xini = $_GET["xini"];
$yini = $_GET["yini"];
$xfin = $_GET["xfin"];
$yfin = $_GET["yfin"];
$res = imagecreatetruecolor (
$xfin-$xini, $yfin-$yini);
imagecopy($res, $img, 0, 0,
$xini, $yini,
$xfin-$xini, $yfin-$yini);
header("Content-type: image/png");
imagepng($res);
?>

Se le pueden añadir más funcionalidades, pero para ir empezando creo que está bien así.

Ejemplo

Te puedes bajar las fuentes aquí

Los comentarios están cerrados.