File size: 5,032 Bytes
d4a2b4e
 
 
 
 
76c1c87
d4a2b4e
 
736c84d
d4a2b4e
 
 
 
 
 
 
736c84d
 
 
d4a2b4e
 
736c84d
d4a2b4e
736c84d
d4a2b4e
736c84d
d4a2b4e
 
736c84d
 
 
 
 
 
 
 
 
d4a2b4e
736c84d
d4a2b4e
 
76c1c87
d4a2b4e
76c1c87
d4a2b4e
 
 
 
76c1c87
736c84d
 
 
 
76c1c87
cfd100f
736c84d
76c1c87
 
d4a2b4e
 
 
 
 
 
736c84d
 
 
 
 
 
 
 
 
 
 
 
 
 
cfd100f
736c84d
cfd100f
 
 
 
 
 
76c1c87
 
736c84d
76c1c87
 
 
 
cfd100f
736c84d
cfd100f
736c84d
cfd100f
 
 
 
 
 
 
736c84d
 
 
 
 
cfd100f
736c84d
cfd100f
d4a2b4e
736c84d
 
 
 
d4a2b4e
205e25d
76c1c87
 
205e25d
d4a2b4e
 
 
 
38eea4d
5ccbbd2
205e25d
d4a2b4e
 
736c84d
205e25d
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
# -*- 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()