███╗ ███╗███████╗████████╗ █████╗ ███████╗ ██████╗██████╗ ██╗ ██╗██████╗
████╗ ████║██╔════╝╚══██╔══╝██╔══██╗██╔════╝██╔════╝██╔══██╗██║ ██║██╔══██╗
██╔████╔██║█████╗ ██║ ███████║███████╗██║ ██████╔╝██║ ██║██████╔╝
██║╚██╔╝██║██╔══╝ ██║ ██╔══██║╚════██║██║ ██╔══██╗██║ ██║██╔══██╗
██║ ╚═╝ ██║███████╗ ██║ ██║ ██║███████║╚██████╗██║ ██║╚██████╔╝██████╔╝
╚═╝ ╚═╝╚══════╝ ╚═╝ ╚═╝ ╚═╝╚══════╝ ╚═════╝╚═╝ ╚═╝ ╚═════╝ ╚═════╝
CLEANER V.1.0
Herramienta profesional CLI para eliminar metadatos EXIF, GPS y timestamps de imágenes de forma masiva
- Descripción
- Características Principales
- Capturas de Pantalla
- Instalación
- Uso
- Cómo Funciona
- Formatos Soportados
- Estructura del Proyecto
- Dependencias
- Casos de Uso
- Roadmap
- Contribuciones
- Créditos
- Licencia
MetaScrub es una herramienta CLI (Command Line Interface) avanzada desarrollada en Python 3.8+, diseñada para profesionales de ciberseguridad, forense digital, fotógrafos y cualquier persona que necesite proteger su privacidad al compartir imágenes.
Con una arquitectura orientada a objetos y una interfaz colorida e intuitiva, MetaScrub elimina completamente los metadatos sensibles de tus imágenes sin comprometer la calidad visual, creando copias limpias mientras mantiene intactos los archivos originales.
💡 Ideal para: Protección de privacidad, análisis forense, compliance GDPR, publicación segura de imágenes en redes sociales, y limpieza masiva de bibliotecas fotográficas.
|
|
|
|
| Característica | Descripción |
|---|---|
| Zero Data Loss | Calidad de imagen preservada al 95% (JPEG) y 100% (PNG) |
| Type Hints | Código completamente tipado para mayor mantenibilidad |
| Clean Code | Arquitectura OOP con clase MetadataCleaner |
| Error Tracking | Sistema de logging de errores con reporte final |
| Docstrings | Documentación inline en todos los métodos |
| Multi-Format | Soporte JPG, JPEG, PNG y WEBP |
🔍 Scanning for images...
Found 150 image(s) to process
🧹 Cleaning metadata: 100%|████████████████| 150/150 [00:15<00:00]
============================================================
📊 PROCESSING REPORT
============================================================
✅ Successfully processed: 148
❌ Errors encountered: 2
⚠️ Error Details:
• corrupted_image.jpg: cannot identify image file
• invalid.png: Truncated file
📁 Clean images saved to: C:\Photos_Clean
============================================================
Input directory: C:\Users\Photos\Vacation
Output directory: C:\Users\Photos\Vacation_Clean
Processing: IMG_3421.jpg
Processing: IMG_3422.jpg
Processing: screenshot_001.png
...
🎯 Resultado: La imagen visual se mantiene idéntica, pero toda la información sensible ha sido eliminada permanentemente.
Asegúrate de tener instalado Python 3.8 o superior en tu sistema:
python --version# 1. Clona el repositorio
git clone https://github.com/qpbo/Metadata-Cleaner.git
# 2. Accede al directorio
cd Metadata-Cleaner
# 3. Instala las dependencias
pip install -r requirements.txt
# 4. Ejecuta la herramienta
python main.py --help# Instala las dependencias manualmente
pip install Pillow tqdm coloramaPara verificar que todo está correctamente instalado:
python main.py --helpSi ves el mensaje de ayuda con todas las opciones, ¡la instalación fue exitosa! 🎉
-
Ejecuta el script con directorios de entrada y salida:
python main.py --input "./mis_fotos" --output "./fotos_limpias"
-
La herramienta procesará recursivamente todas las imágenes encontradas
-
Revisa el reporte final con estadísticas de procesamiento
python main.py --input <directorio_entrada> --output <directorio_salida> [--verbose]Argumentos:
--input/-i: Directorio con imágenes a limpiar (requerido)--output/-o: Directorio para guardar imágenes limpias (requerido)--verbose/-v: Activar salida detallada (opcional)
python main.py --input "./vacation_photos" --output "./vacation_clean"python main.py --input "C:/Users/Carlo/Pictures" --output "C:/Users/Carlo/Pictures_Clean"python main.py --input "./test_images" --output "./test_clean" --verbose# Estructura de entrada:
# photos/
# ├── 2024/
# │ ├── enero/
# │ └── febrero/
# └── 2025/
python main.py --input "./photos" --output "./photos_clean"
# Resultado preserva la estructura:
# photos_clean/
# ├── 2024/
# │ ├── enero/ (imágenes limpias)
# │ └── febrero/ (imágenes limpias)
# └── 2025/ (imágenes limpias)MetaScrub utiliza una técnica elegante y efectiva basada en la librería Pillow (PIL):
# 1. Abrir imagen (carga píxeles, NO EXIF)
with Image.open(input_image) as img:
# 2. Extraer solo datos de píxeles
data = list(img.getdata())
# 3. Crear nueva imagen SIN metadatos
clean_img = Image.new(img.mode, img.size)
clean_img.putdata(data)
# 4. Guardar SIN parámetro 'exif'
# Resultado: Imagen limpia sin metadata
clean_img.save(output_image, quality=95, optimize=True)Clave del proceso:
Image.save()de Pillow NO copia automáticamente los metadatos EXIF- Los metadatos solo se preservan si se pasa explícitamente el parámetro
exif= - Al omitir este parámetro, creamos una copia completamente limpia
- Esta técnica funciona en todos los formatos soportados (JPEG, PNG, WEBP)
1. Escaneo Recursivo
└─> Encuentra todas las imágenes (.jpg, .jpeg, .png, .webp)
2. Validación
└─> Verifica que input existe y crea output
3. Procesamiento por Lotes
├─> Para cada imagen:
│ ├─> Abre y lee píxeles
│ ├─> Crea nueva imagen sin metadata
│ ├─> Guarda en estructura paralela
│ └─> Maneja errores individualmente
└─> Continúa sin interrumpirse si hay errores
4. Reporte Final
└─> Estadísticas: procesadas, errores, ubicación
| Formato | Extensión | Calidad | Metadata Eliminada |
|---|---|---|---|
| JPEG | .jpg, .jpeg, .JPG, .JPEG |
95% (configurable) | ✅ EXIF, GPS, timestamps |
| PNG | .png, .PNG |
Sin pérdida (100%) | ✅ Metadata chunks |
| WEBP | .webp, .WEBP |
95% (configurable) | ✅ EXIF, XMP |
EXIF Data:
- Marca y modelo de cámara
- Configuración de disparo (ISO, apertura, velocidad)
- Información de lente y distancia focal
- Flash utilizado
- Balance de blancos
- Software de edición
GPS Data:
- Latitud y longitud exactas
- Altitud
- Timestamp GPS
- Dirección de la imagen
Timestamps:
- Fecha y hora de creación original
- Fecha y hora de modificación
- Fecha y hora de digitalización
Otros:
- Copyright y autoría
- Descripción y comentarios
- Miniaturas embebidas
- Perfiles de color
Metadata-Cleaner/
│
├── 📄 main.py # Script principal (295 líneas)
│ ├── Clase: MetadataCleaner
│ │ ├── __init__() # Inicialización y validación
│ │ ├── _validate_paths() # Validar input/output
│ │ ├── _find_images() # Búsqueda recursiva
│ │ ├── _get_output_path() # Calcular ruta de salida
│ │ ├── _clean_image_metadata() # Limpieza EXIF
│ │ ├── process() # Orquestador principal
│ │ └── _print_report() # Reporte final
│ └── main() # Entry point CLI
│
├── 📄 requirements.txt # Dependencias del proyecto
│ ├── Pillow>=10.0.0
│ ├── tqdm>=4.65.0
│ └── colorama>=0.4.6
│
├── 📄 README.md # Documentación completa
│
└── 📄 LICENSE # Licencia MIT (opcional)
main.py
│
├── [Imports y Configuración]
│ ├── PIL (Procesamiento de imágenes)
│ ├── tqdm (Barras de progreso)
│ ├── colorama (Colores CLI)
│ └── pathlib (Manejo de rutas)
│
├── [Clase MetadataCleaner] # Backend de operaciones
│ ├── SUPPORTED_FORMATS # Constante de formatos
│ ├── __init__() # Constructor
│ ├── _validate_paths() # Validación de directorios
│ ├── _find_images() # Búsqueda recursiva
│ ├── _get_output_path() # Cálculo de rutas
│ ├── _clean_image_metadata() # Limpieza de metadata
│ ├── process() # Proceso principal
│ └── _print_report() # Reporte de estadísticas
│
└── [main()] # Entry point
├── ArgumentParser # CLI con argparse
├── Instancia de MetadataCleaner
└── Exception handling global
El proyecto utiliza las siguientes librerías de Python:
| Librería | Versión | Propósito |
|---|---|---|
| Pillow | >=10.0.0 |
Procesamiento de imágenes y eliminación de EXIF |
| tqdm | >=4.65.0 |
Barras de progreso y feedback visual |
| colorama | >=0.4.6 |
Colores y estilización de la interfaz CLI |
Pillow>=10.0.0
tqdm>=4.65.0
colorama>=0.4.6pip install -r requirements.txtO instalar individualmente:
pip install Pillow tqdm coloramaEscenario: Quieres compartir fotos de vacaciones en redes sociales sin revelar tu ubicación exacta.
python main.py --input "./vacation_2024" --output "./vacation_2024_safe"Resultado: Imágenes sin GPS, sin metadatos de cámara, listas para compartir de forma anónima.
Escenario: Tu empresa necesita publicar imágenes en su sitio web sin incluir metadata personal.
python main.py --input "./corporate_photos" --output "./web_ready_photos" --verboseResultado: Imágenes sin timestamps, sin información de autor, cumpliendo con regulaciones de privacidad.
Escenario: Necesitas crear copias de evidencia fotográfica sin metadata para presentación pública.
python main.py --input "./evidence_raw" --output "./evidence_clean"Resultado: Copias seguras sin metadata sensible, manteniendo los originales intactos.
Escenario: Periodista o activista que necesita publicar fotos sin comprometer su identidad o ubicación.
python main.py --input "./field_photos" --output "./anonymous_photos" --verboseResultado: Imágenes completamente anónimas, sin trazabilidad geográfica o temporal.
Escenario: Tienes miles de fotos antiguas que quieres limpiar antes de archivarlas en la nube.
python main.py --input "C:/Photos/2010-2020" --output "C:/Photos_Clean/2010-2020"Resultado: Biblioteca completa procesada con estructura de carpetas preservada.
- Limpieza completa de metadatos EXIF
- Soporte JPG, JPEG, PNG, WEBP
- Procesamiento recursivo de directorios
- Barra de progreso con tqdm
- Interfaz CLI colorida
- Reporte final de estadísticas
- Manejo robusto de errores
- Type hints completos
- Modo de análisis (preview de metadata sin eliminar)
- Exportación de metadata a JSON/CSV antes de limpiar
- Opción de backup automático
- Soporte para más formatos (TIFF, BMP, GIF)
- Preservar metadata selectiva (ej: solo eliminar GPS)
- Modo dry-run (simular sin ejecutar)
- Interfaz gráfica (GUI) opcional con tkinter
- Procesamiento paralelo multi-thread
- Compresión inteligente de imágenes
- Integración con cloud storage (Google Drive, Dropbox)
- Creación de reportes en PDF
- API REST para integración con otros servicios
- Docker container para deployment
¿Tienes una sugerencia? ¡Abre un issue!
Las contribuciones son bienvenidas y se agradecen enormemente. Si deseas contribuir:
- Fork el repositorio
- Crea una rama para tu feature (
git checkout -b feature/AmazingFeature) - Haz commit de tus cambios (
git commit -m 'Add some AmazingFeature') - Push a la rama (
git push origin feature/AmazingFeature) - Abre un Pull Request
- Sé respetuoso con otros contribuidores
- Reporta bugs de manera constructiva
- Documenta tus cambios claramente
- Sigue el estilo de código existente (PEP 8)
- Incluye type hints en todo código nuevo
Si encuentras un bug, por favor abre un issue con:
- Descripción del problema
- Pasos para reproducirlo
- Comportamiento esperado vs. actual
- Screenshots (si aplica)
- Información del sistema (OS, versión de Python)
- Tipo y tamaño de imágenes afectadas
- Comunidad de Python por Pillow, tqdm y colorama
- Inspiración de herramientas forenses profesionales
- Todos los contribuidores futuros
Este proyecto está licenciado bajo la Licencia MIT - ver el archivo LICENSE para más detalles.
MIT License
Copyright (c) 2026 Carliyo
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.

