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);
}
?>