# -*- coding: utf-8 -*- import cv2 import numpy as np from PIL import Image from PIL.ExifTags import TAGS import os from datetime import datetime import tempfile def obtener_metadatos(imagen): """ Obtiene los metadatos de la imagen. """ try: exif_data = imagen._getexif() if not exif_data: return {} return {TAGS.get(tag_id, tag_id): value for tag_id, value in exif_data.items()} except Exception as e: print(f"Error al obtener metadatos: {e}") return {} def realizar_ela(imagen, quality=95, scale=100): """ Realiza el Error Level Analysis (ELA) en la imagen. """ try: imagen_cv = cv2.cvtColor(np.array(imagen), cv2.COLOR_RGB2BGR) temp_path = "temp_image.jpg" cv2.imwrite(temp_path, imagen_cv, [cv2.IMWRITE_JPEG_QUALITY, quality]) imagen_comprimida = cv2.imread(temp_path) diferencia = cv2.absdiff(imagen_cv, imagen_comprimida) ela_imagen = scale * diferencia ela_imagen = cv2.cvtColor(ela_imagen, cv2.COLOR_BGR2GRAY) os.remove(temp_path) return ela_imagen except Exception as e: print(f"Error al realizar ELA: {e}") return None def analizar_manipulacion(imagen, ela_imagen): """ Analiza si la imagen ha sido manipulada usando ELA como referencia principal. """ manipulada = False razones = [] # Validar análisis ELA if ela_imagen is None: razones.append("No se pudo realizar el análisis ELA.") else: promedio_ela = np.mean(ela_imagen) if promedio_ela > 10: # Umbral basado en pruebas razones.append("El análisis ELA sugiere posibles alteraciones. Esto podría deberse a ediciones o ajustes automáticos del dispositivo.") manipulada = True else: razones.append("El análisis ELA no sugiere alteraciones.") return manipulada, razones def procesar_imagen(archivo_imagen): try: imagen = Image.open(archivo_imagen) nombre_archivo = os.path.basename(archivo_imagen) stats = os.stat(archivo_imagen) tamaño_archivo = stats.st_size / 1024 fecha_creacion = datetime.fromtimestamp(stats.st_ctime).strftime('%Y-%m-%d %H:%M:%S') fecha_modificacion = datetime.fromtimestamp(stats.st_mtime).strftime('%Y-%m-%d %H:%M:%S') info_basica = f""" Información básica de la imagen: Nombre del archivo: {nombre_archivo} Tamaño: {tamaño_archivo:.2f} KB Fecha de creación: {fecha_creacion} Fecha de modificación: {fecha_modificacion} """ # Obtener metadatos (mostrar si están disponibles) metadatos = obtener_metadatos(imagen) if metadatos: metadatos_info = "\nMetadatos EXIF encontrados:\n" for key, value in metadatos.items(): metadatos_info += f"- {key}: {value}\n" else: metadatos_info = "\nLa imagen no contiene metadatos EXIF (esto no implica manipulación)." # Realizar ELA ela_imagen = realizar_ela(imagen) # Analizar manipulación basado en ELA manipulada, razones = analizar_manipulacion(imagen, ela_imagen) # Construir mensaje principal y detallado if manipulada: resultado_principal = "**Conclusión:** Se detectaron posibles alteraciones en la imagen.\n" else: resultado_principal = "**Conclusión:** No se detectaron alteraciones evidentes en la imagen.\n" razones_detalle = "\nRazones del análisis:\n" for razon in razones: razones_detalle += f"- {razon}\n" resultado_final = info_basica + metadatos_info + "\n" + resultado_principal + razones_detalle if ela_imagen is not None: with tempfile.NamedTemporaryFile(suffix=".png", delete=False) as tmp_file: cv2.imwrite(tmp_file.name, ela_imagen) ela_image_path = tmp_file.name return ela_image_path, resultado_final else: return None, resultado_final + "\n(No se generó ELA debido a un error técnico.)" except Exception as e: error_msg = f"Error procesando la imagen: {e}" print(error_msg) return None, error_msg # Interfaz de GRADIO con un tema moderno import gradio as gr # Usar un tema moderno (por ejemplo, "huggingface") iface = gr.Interface( fn=procesar_imagen, inputs=gr.Image(type="filepath", label="Sube una imagen"), outputs=[gr.Image(label="Error Level Analysis (ELA)"), gr.Textbox(label="Resultado del análisis")], title=" 🔍 Error Level Analysis (ELA)", description="Este programa diseñado por José R. Leonett es para analizar imágenes en busqueda de manipulación utilizando la técnica de Error Level Analysis (ELA). Creado para el grupo de Peritos Forenses Digitales de Guatemala [www.forensedigital.gt](https://www.forensedigital.gt).", theme="huggingface" # Tema moderno ) # Lanzar la interfaz iface.launch()