389 lines
8.2 KiB
Markdown
389 lines
8.2 KiB
Markdown
# Logo-Imagenes
|
|
|
|
Herramientas en Python para convertir imágenes a formato JPEG y añadir automáticamente un logotipo sobre las imágenes procesadas.
|
|
|
|
El proyecto permite:
|
|
|
|
* Convertir archivos Sony RAW `.ARW` a `.JPG`.
|
|
* Convertir archivos `.HEIC` a `.JPG`.
|
|
* Añadir un logotipo PNG sobre imágenes JPEG o PNG.
|
|
* Mantener la estructura de subdirectorios entre las carpetas de entrada y salida.
|
|
* Generar nombres únicos basados en la fecha de modificación del archivo original.
|
|
|
|
## Estructura del proyecto
|
|
|
|
```text
|
|
Logo-Imagenes/
|
|
├── arw_to_jpg.py
|
|
├── heic_to_jpg.py
|
|
├── nef_to_jpg.py
|
|
├── main.py
|
|
├── logo.png
|
|
├── conlogo/
|
|
├── withoutlogo/
|
|
└── README.md
|
|
```
|
|
|
|
### Directorios
|
|
|
|
| Ruta | Descripción |
|
|
| -------------- | --------------------------------------------------------- |
|
|
| `withoutlogo/` | Imágenes de entrada sobre las que se añadirá el logotipo. |
|
|
| `conlogo/` | Imágenes generadas con el logotipo. |
|
|
| `arw/` | Archivos `.ARW` que se convertirán a JPEG. |
|
|
| `heic2/` | Archivos `.HEIC` que se convertirán a JPEG. |
|
|
| `logo.png` | Logotipo utilizado por defecto. |
|
|
|
|
Los directorios de entrada pueden contener subdirectorios. El script `main.py` reproduce esa estructura dentro de `conlogo/`.
|
|
|
|
## Requisitos
|
|
|
|
* Python 3.10 o superior.
|
|
* Pillow.
|
|
* rawpy.
|
|
* OpenCV.
|
|
* `libheif-examples`, que proporciona el comando `heif-convert`.
|
|
|
|
### Instalación en Debian o Ubuntu
|
|
|
|
```bash
|
|
sudo apt update
|
|
sudo apt install python3 python3-venv libheif-examples
|
|
```
|
|
|
|
Crea y activa un entorno virtual:
|
|
|
|
```bash
|
|
python3 -m venv .venv
|
|
source .venv/bin/activate
|
|
```
|
|
|
|
Instala las dependencias de Python:
|
|
|
|
```bash
|
|
pip install Pillow rawpy opencv-python
|
|
```
|
|
|
|
Opcionalmente, crea un archivo `requirements.txt`:
|
|
|
|
```text
|
|
Pillow
|
|
rawpy
|
|
opencv-python
|
|
```
|
|
|
|
E instala las dependencias mediante:
|
|
|
|
```bash
|
|
pip install -r requirements.txt
|
|
```
|
|
|
|
## Uso
|
|
|
|
Todos los comandos deben ejecutarse desde el directorio raíz del repositorio.
|
|
|
|
```bash
|
|
cd Logo-Imagenes
|
|
```
|
|
|
|
## Añadir el logotipo a imágenes
|
|
|
|
El script `main.py` procesa recursivamente las imágenes situadas en `withoutlogo/`.
|
|
|
|
Formatos admitidos:
|
|
|
|
* `.jpg`
|
|
* `.jpeg`
|
|
* `.png`
|
|
|
|
### Preparación
|
|
|
|
Copia las imágenes de entrada:
|
|
|
|
```bash
|
|
cp /ruta/a/las/imagenes/* withoutlogo/
|
|
```
|
|
|
|
También puedes utilizar subdirectorios:
|
|
|
|
```text
|
|
withoutlogo/
|
|
├── evento-1/
|
|
│ ├── foto-01.jpg
|
|
│ └── foto-02.jpg
|
|
└── evento-2/
|
|
└── foto-03.png
|
|
```
|
|
|
|
Coloca el logotipo en:
|
|
|
|
```text
|
|
logo.png
|
|
```
|
|
|
|
El logotipo debe ser una imagen PNG con transparencia.
|
|
|
|
### Ejecución
|
|
|
|
```bash
|
|
python main.py
|
|
```
|
|
|
|
Las imágenes procesadas se guardarán en `conlogo/`:
|
|
|
|
```text
|
|
conlogo/
|
|
├── evento-1/
|
|
│ ├── 20260720_154500.jpg
|
|
│ └── 20260720_154535.jpg
|
|
└── evento-2/
|
|
└── 20260720_160010.png
|
|
```
|
|
|
|
### Comportamiento del logotipo
|
|
|
|
El script:
|
|
|
|
1. Lee la orientación EXIF de la imagen.
|
|
2. Corrige la rotación cuando es necesario.
|
|
3. Redimensiona el logotipo para que no supere el 35 % del lado menor de la imagen.
|
|
4. Añade un margen equivalente al 3,5 % del lado menor.
|
|
5. Sitúa el logotipo en la esquina inferior izquierda.
|
|
6. Guarda el resultado dentro de `conlogo/`.
|
|
|
|
Cuando ya existe un archivo con el mismo nombre, añade un sufijo numérico:
|
|
|
|
```text
|
|
20260720_154500.jpg
|
|
20260720_154500_1.jpg
|
|
20260720_154500_2.jpg
|
|
```
|
|
|
|
## Convertir ARW a JPG
|
|
|
|
El script `arw_to_jpg.py` busca archivos `.ARW` dentro del directorio `arw/` y sus subdirectorios.
|
|
|
|
### Preparación
|
|
|
|
```bash
|
|
mkdir -p arw
|
|
cp /ruta/a/las/fotos/*.ARW arw/
|
|
```
|
|
|
|
### Ejecución
|
|
|
|
```bash
|
|
python arw_to_jpg.py
|
|
```
|
|
|
|
Cada archivo convertido se guarda junto al archivo original:
|
|
|
|
```text
|
|
arw/
|
|
├── DSC00001.ARW
|
|
├── DSC00001.jpg
|
|
├── DSC00002.ARW
|
|
└── DSC00002.jpg
|
|
```
|
|
|
|
Los JPEG se generan con calidad `100`.
|
|
|
|
Después de convertirlos, puedes moverlos a `withoutlogo/` para aplicar el logotipo:
|
|
|
|
```bash
|
|
find arw -type f -iname '*.jpg' -exec cp --parents {} withoutlogo/ \;
|
|
```
|
|
|
|
## Convertir HEIC a JPG
|
|
|
|
El script `heic_to_jpg.py` busca imágenes HEIC dentro de `heic2/`.
|
|
|
|
### Preparación
|
|
|
|
```bash
|
|
mkdir -p heic2
|
|
cp /ruta/a/las/fotos/*.HEIC heic2/
|
|
```
|
|
|
|
### Ejecución
|
|
|
|
```bash
|
|
python heic_to_jpg.py
|
|
```
|
|
|
|
La conversión utiliza:
|
|
|
|
```bash
|
|
heif-convert -q 100 entrada.HEIC salida.jpg
|
|
```
|
|
|
|
Los archivos JPEG se guardan en el mismo directorio que los originales.
|
|
|
|
## Conversión de NEF
|
|
|
|
El archivo `nef_to_jpg.py` no convierte actualmente archivos Nikon `.NEF`.
|
|
|
|
Su contenido es una copia del conversor HEIC:
|
|
|
|
* Busca archivos `.HEIC`.
|
|
* Utiliza `heif-convert`.
|
|
* Trabaja sobre el directorio `heic2/`.
|
|
|
|
Por tanto, no debe considerarse funcional como conversor NEF.
|
|
|
|
Para convertir archivos `.NEF`, puede utilizarse `rawpy`, con una implementación equivalente a la utilizada para ARW.
|
|
|
|
Ejemplo:
|
|
|
|
```python
|
|
import os
|
|
|
|
import cv2
|
|
import rawpy
|
|
|
|
directory = "nef"
|
|
|
|
for root, _, files in os.walk(directory):
|
|
for filename in files:
|
|
if not filename.lower().endswith(".nef"):
|
|
continue
|
|
|
|
input_path = os.path.join(root, filename)
|
|
output_path = os.path.splitext(input_path)[0] + ".jpg"
|
|
|
|
print(f"Convirtiendo {input_path} → {output_path}")
|
|
|
|
with rawpy.imread(input_path) as raw:
|
|
rgb = raw.postprocess()
|
|
|
|
bgr = cv2.cvtColor(rgb, cv2.COLOR_RGB2BGR)
|
|
|
|
success = cv2.imwrite(
|
|
output_path,
|
|
bgr,
|
|
[int(cv2.IMWRITE_JPEG_QUALITY), 100],
|
|
)
|
|
|
|
if not success:
|
|
raise RuntimeError(f"No se pudo guardar {output_path}")
|
|
```
|
|
|
|
## Configuración
|
|
|
|
El logotipo utilizado por `main.py` se define mediante:
|
|
|
|
```python
|
|
logo_hor = "./logo.png"
|
|
logo_file = logo_hor
|
|
```
|
|
|
|
También existe una ruta absoluta alternativa:
|
|
|
|
```python
|
|
logo_ver = "/home/jesusjmma/Documents/Logos/CEEBI/CEEBI/Logo CEEBI vertical blanco.png"
|
|
```
|
|
|
|
Esa ruta depende del equipo del autor y no es portable. Se recomienda utilizar únicamente rutas relativas al repositorio.
|
|
|
|
## Flujo de trabajo recomendado
|
|
|
|
### Fotografías ARW
|
|
|
|
```bash
|
|
python arw_to_jpg.py
|
|
find arw -type f -iname '*.jpg' -exec cp --parents {} withoutlogo/ \;
|
|
python main.py
|
|
```
|
|
|
|
### Fotografías HEIC
|
|
|
|
```bash
|
|
python heic_to_jpg.py
|
|
find heic2 -type f -iname '*.jpg' -exec cp --parents {} withoutlogo/ \;
|
|
python main.py
|
|
```
|
|
|
|
### Fotografías JPG o PNG
|
|
|
|
```bash
|
|
cp /ruta/a/las/imagenes/* withoutlogo/
|
|
python main.py
|
|
```
|
|
|
|
## Limitaciones actuales
|
|
|
|
* Los nombres de los directorios están definidos directamente en el código.
|
|
* `heic_to_jpg.py` contiene rutas absolutas específicas del equipo del autor.
|
|
* `nef_to_jpg.py` no implementa conversión NEF.
|
|
* No existe una interfaz de línea de comandos.
|
|
* No se validan todos los posibles modos de color de las imágenes.
|
|
* Los metadatos EXIF pueden perderse al guardar la imagen procesada.
|
|
* El logotipo se carga una sola vez y se redimensiona durante el procesamiento.
|
|
* No existe una gestión centralizada de errores ni un sistema de registros.
|
|
* Los scripts ejecutan su lógica directamente al importarse.
|
|
* Las imágenes procesadas pueden ocupar bastante espacio al guardarse con calidad máxima.
|
|
|
|
## Mejoras recomendadas
|
|
|
|
* Sustituir las rutas absolutas por rutas relativas.
|
|
* Añadir argumentos de línea de comandos con `argparse`.
|
|
* Unificar los conversores ARW y NEF.
|
|
* Permitir seleccionar las carpetas de entrada y salida.
|
|
* Permitir configurar posición, tamaño y margen del logotipo.
|
|
* Añadir un archivo `requirements.txt`.
|
|
* Añadir pruebas automatizadas.
|
|
* Preservar los metadatos EXIF.
|
|
* Separar el código en funciones reutilizables.
|
|
* Añadir un archivo `.gitignore`.
|
|
* Evitar versionar fotografías originales y resultados generados.
|
|
|
|
## `.gitignore` recomendado
|
|
|
|
```gitignore
|
|
# Python
|
|
__pycache__/
|
|
*.py[cod]
|
|
.venv/
|
|
venv/
|
|
|
|
# Editores
|
|
.vscode/
|
|
.idea/
|
|
|
|
# Entradas y resultados
|
|
arw/*
|
|
heic2/*
|
|
nef/*
|
|
withoutlogo/*
|
|
conlogo/*
|
|
|
|
# Mantener los directorios
|
|
!arw/.gitkeep
|
|
!heic2/.gitkeep
|
|
!nef/.gitkeep
|
|
!withoutlogo/.gitkeep
|
|
!conlogo/.gitkeep
|
|
|
|
# Fotografías RAW
|
|
*.arw
|
|
*.ARW
|
|
*.nef
|
|
*.NEF
|
|
*.heic
|
|
*.HEIC
|
|
```
|
|
|
|
Para conservar los directorios vacíos en Git:
|
|
|
|
```bash
|
|
touch arw/.gitkeep
|
|
touch heic2/.gitkeep
|
|
touch nef/.gitkeep
|
|
touch withoutlogo/.gitkeep
|
|
touch conlogo/.gitkeep
|
|
```
|
|
|
|
## Licencia
|
|
|
|
Copyright © 2026 Jesús Maldonado. Todos los derechos reservados.
|