|
|
|
|
|
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 = [] |
|
|
|
|
|
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: |
|
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} |
|
""" |
|
|
|
|
|
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)." |
|
|
|
|
|
ela_imagen = realizar_ela(imagen) |
|
|
|
|
|
manipulada, razones = analizar_manipulacion(imagen, ela_imagen) |
|
|
|
|
|
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 |
|
|
|
|
|
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." |
|
) |
|
|
|
|
|
iface.launch() |
|
|