# -*- 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 import gradio as gr 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="Análisis de Manipulación de Imágenes", description="Sube una imagen para analizar posibles manipulaciones usando principalmente ELA." ) # Lanzar la interfaz iface.launch()