Laboratorio: Comparar imágenes mediante PHP
Voy a intentar responder de una forma un poco más completa la pregunta que nos hacía David sobre la forma de comparar dos imágenes. Aunque este tema es muy intenso y en algunos casos bastante complicado, vamos a intentar simplificarlo en dos casos: imágenes de distinto tamaño y distinto contenido en la imagen.
Si las imágenes son de distinto tamaño diremos que son distintas imágenes, no nos pararemos a ver el contenido. Si tienen el mismo tamaño, buscaremos que parte de la imagen es la que ha cambiado y la señalaremos con un rectángulo rojo.
El funcionamiento del script es sencillo:
- Primero recibimos las dos imágenes (en este caso ambas son PNG para facilitar el script), si la imagen seleccionada no se ha elegido, se devuelve la imagen original (esto es solo para evitar dar un error).
- Se cargan las dos imágenes.
- Si las imágenes tienen distinto tamaño se devuelve una imagen del tamaño de la original con un texto que indica que son de distinto tamaño.
- Si las imágenes tienen el mismo tamaño se comprueba el contenido de ambas, se van recorriendo ambas imágenes punto a punto (usando coordenadas x e y) comprobando el color rgb de ambas.
- Si no ha habido diferencias entre las imágenes se devuelve una imagen del tamaño de la original con un texto que indica que son la misma imagen.
- Cuando se encuentra un punto con distinto color en las dos imágenes, se comprueba si el punto es el que tiene menor X o menor Y encontrado y si es así nos quedamos con la coordenada X o Y menor, igual para el punto mayor. Así lo que conseguimos es el recuadro que enmarca todos los puntos diferentes entre ambas imágenes. Cuando hemos acabado de recorrer las imágenes, devolvemos la imagen seleccionada con el recuadro dibujado.
<?php
// Cargamos las imágenes
$origen = $_GET["img1"];
$destino = $_GET["img2"];
$im1 = imagecreatefrompng (getcwd()."/".$origen);
if (!$destino) {
header("Content-type: image/png");
imagepng($im1);
} else {
$im2 = imagecreatefrompng (getcwd()."/".$destino);
// Creamos la imagen resultante
$im3 = imagecreate(ImageSX($im1), ImageSY($im1));
if (ImageSX($im1) == ImageSX($im2) && ImageSY($im1) == ImageSY($im2)) {
// Tienen el mismo tamaño
$rojo = imagecolorallocate($im3, 255, 0, 0);
// Compruebo la zona que tiene distintos pixels
$xmin = ImageSX($im1);
$xmax = 0;
$ymin = ImageSY($im1);
$ymax = 0;
$ok = false;
for ($j= 0; $j<ImageSY($im1); $j++) {
for ($i= 0; $i<ImageSX($im1); $i++) {
$rgb1 = imagecolorat($im1, $i, $j);
$rgb2 = imagecolorat($im2, $i, $j);
if ($rgb1 != $rgb2) {
$ok = true;
$xmin = ($i < $xmin)? $i : $xmin;
$ymin = ($j < $ymin)? $j : $ymin;
$xmax = ($i > $xmax)? $i : $xmax;
$ymax = ($j > $ymax)? $j : $ymax;
}
}
}
if (!$ok) {
// Son iguales
$negro = imagecolorallocate($im3, 0, 0, 0);
imagestring($im3, 10, 5, 5, "Son iguales", $negro);
} else {
// Son distintas
// Copio la imagen 2 sobre la resultante
imagecopy($im3, $im2, 0, 0, 0, 0, ImageSX($im2), ImageSY($im2));
// Señalo donde difieren
imagerectangle($im3, $xmin, $ymin, $xmax, $ymax, $rojo);
}
} else {
$rojo = imagecolorallocate($im3, 255, 0, 0);
$negro = imagecolorallocate($im3, 0, 0, 0);
imagestring($im3, 10, 5, 5, "Distinto ancho y alto", $negro);
}
/* Devolvemos la imagen */
header("Content-type: image/png");
imagepng($im3);
}
?>

Interesante estudio sobre comparativa de sentencias en PHP5 que obtienen el mismo resultado, para conocer cual de ellas es la más rápida. Por ejemplo: es más rápido concatenar una cadena a una variable usando el punto (.) que incluyéndo la variable entre comillas dobles, para expresiones regulares es más rápido usar preg_match que eregi, es 8 veces más rápido usar explode que split. También es una buena referencia para saber como hacer lo mismo de distintas formas. Pero lo que más me ha sorprendido es que comparando con PHP4 las expresiones regulares se han vuelto más lentas (casi 7 veces más rápido en PHP4 que en PHP5), lo cual me hace pensar que o bien es debido a una mejora que completa las expresiones regulares, o antes no se hacÃan muy bien, porque ir a peor no tiene mucho sentido.
MAMP es un instalador de Apache, MySQL y PHP para Mac OS X sencillo y que con unos pocos clicks ya tenemos instaladas las aplicaciones más habituales para desarrollo web.
