Mostrando las entradas con la etiqueta bash. Mostrar todas las entradas
Mostrando las entradas con la etiqueta bash. Mostrar todas las entradas

martes, 16 de julio de 2024

Script para automatizar la limpieza con BleachBit en antiX

Script: clean_with_bleachbit.sh


BleachBit . Personalmente yo la uso con antiX. Algunas características que lo hacen interesante:

  • Limpieza profunda: BleachBit es conocido como "el CCleaner para Linux" por su capacidad de limpiar profundamente los sistemas, eliminando cachés, registros, cookies, archivos temporales y más.
  • Soporte para múltiples aplicaciones: Puede limpiar archivos y cachés de una amplia gama de aplicaciones, como navegadores web, suites de oficina y programas de mensajería.
  • Interfaz gráfica y de línea de comandos: Ofrece una interfaz gráfica sencilla y también puede ser usado desde la línea de comandos, lo que lo hace versátil para diferentes tipos de usuarios.
  • Desfragmentación y trituración de archivos: Puede desfragmentar archivos y triturar archivos para una eliminación segura.
Interface de BleachBit

Ventajas:

  • Eficiencia: Es ligero y consume pocos recursos del sistema.
  • Potencia en la limpieza: Se enfoca específicamente en la limpieza y lo hace de manera efectiva.
  • Flexibilidad: La opción de usarlo desde la línea de comandos lo hace adecuado para scripts y automatización . Aca les dejo un ejemplo de como podría ser incorporado a un script (este script opcionalmente luego podría ser incorporado como una tarea administrativa a través de cron).

Código


#!/bin/bash
# --------------------------------------------------------------------------------------------------------------------------------------
# File: clean_with_bleachbit.sh
# By Julio Alberto Lascano http://drcalambre.blogspot.com/
#________          _________        .__                ___.                  
#\______ \_______  \_   ___ \_____  |  | _____    _____\_ |_________   ____  
# |    |  \_  __ \ /    \  \/\__  \ |  | \__  \  /     \| __ \_  __ \_/ __ \ 
# |    `   \  | \/ \     \____/ __ \|  |__/ __ \|  Y Y  \ \_\ \  | \/\  ___/ 
#/_______  /__|     \______  (____  /____(____  /__|_|  /___  /__|    \___  >
#        \/                \/     \/          \/      \/    \/            \/ 
# --------------------------------------------------------------------------------------------------------------------------------------
# Last modified:2024-07-14
# --------------------------------------------------------------------------------------------------------------------------------------

# Script para automatizar la limpieza con BleachBit
# Asegúrate de tener BleachBit instalado y configurado para ejecutarse desde la línea de comandos

# Configurar las opciones de limpieza de BleachBit
# Puedes encontrar la lista completa de opciones en la documentación de BleachBit o usando `bleachbit --list`

# Lista de opciones de limpieza
options=(
    "apt.autoclean"
    "apt.clean"
    "system.cache"
    "system.tmp"
    "chromium.cache"
    "chromium.dom"
    "chromium.history"
    "chromium.form_history"
    "chromium.search_engines"
    "chromium.sync"
    "chromium.vacuum"
    "firefox.cache"
    "firefox.crash_reports"
    "firefox.dom"
    "firefox.forms"
    "firefox.session_restore"
    "firefox.site_preferences"
    "firefox.vacuum"
    "google_chrome.cache"
    "google_chrome.dom"
    "google_chrome.history"
    "google_chrome.search_engines"
    "google_chrome.vacuum"
)   

# Función para ejecutar la limpieza
run_bleachbit() {
    for option in "${options[@]}"; do
        echo "Limpiando $option"
        bleachbit --clean "$option"
    done
}

# Ejecutar la función de limpieza
run_bleachbit

# Salida del script
echo "Limpieza completada con BleachBit"

Guardar el script en:


 
/usr/local/bin/clean_with_bleachbit.sh

Dar permisos de ejecución al script


chmod +x /usr/local/bin/clean_with_bleachbit.sh

Implementación con CRON

# Editar el archivo crontab para el usuario actual


(crontab -l 2>/dev/null; echo "0 2 * * * /usr/local/bin/clean_with_bleachbit.sh >> /var/log/bleachbit.log 2>&1") | crontab -

En el ejemplo de cron proporcionado programará la ejecución del script clean_with_bleachbit.sh todos los días a las 2:00 AM. Explicación del Cronograma

0 2 * * *: Esta parte del cronograma especifica los momentos en que se ejecutará el script.
0: El minuto en que se ejecutará la tarea (0 significa en el minuto cero de la hora especificada).
2: La hora en que se ejecutará la tarea (2 significa a las 2:00 AM).
*: Cualquier día del mes.
*: Cualquier mes.
*: Cualquier día de la semana.
Interpretación
Minuto (0): El script se ejecutará al minuto 0 de la hora especificada (es decir, al principio de la hora).
Hora (2): El script se ejecutará a las 2:00 AM.
Día del Mes (*): Se ejecutará cualquier día del mes.
Mes (*): Se ejecutará cualquier mes.
Día de la Semana (*): Se ejecutará cualquier día de la semana.
Verificación Después de ejecutar el comando anterior, puedes verificar que la tarea cron se haya configurado correctamente utilizando el siguiente comando:


crontab -l

Implementación con ANACRON

Usar anacron en lugar de cron para tu script de limpieza con BleachBit puede ofrecer varias ventajas, especialmente si estás en un entorno donde el equipo no está encendido constantemente o en horarios específicos.

Aquí están algunas de las ventajas:
  • Ejecución Garantizada: anacron garantiza que las tareas programadas se ejecuten incluso si el equipo estuvo apagado durante el horario programado. En contraste, cron solo ejecuta tareas en momentos específicos y las tareas se pierden si el equipo no está encendido.
  • Flexibilidad de Horarios: anacron permite definir periodos en días para la ejecución de tareas (e.g., diario, semanal, mensual) sin necesidad de especificar una hora exacta, lo que ofrece mayor flexibilidad para equipos que no están siempre encendidos.
  • Fácil Configuración para Tareas Periódicas: Para tareas que necesitan ejecutarse al menos una vez al día, anacron es una opción más sencilla y robusta. En lugar de depender de un cronjob que puede no ejecutarse si el sistema está apagado, anacron simplemente ejecuta la tarea la próxima vez que el sistema esté encendido.
  • Manejo Automático de Retrasos: Si una tarea se retrasa (por ejemplo, porque el equipo estuvo apagado en el momento programado para la ejecución), anacron se encargará de ejecutarla la próxima vez que el equipo esté encendido. Esto asegura que las tareas críticas no se pierdan simplemente porque el equipo no estaba disponible en el momento exacto de la programación, a diferencia de cron, que no reprograma tareas perdidas.

El COMO usar anacron con un usuario común, aunque requiere algunos pasos adicionales en comparación con cron. A continuación, una explicacíon cómo configurar anacron para un usuario común.

Instalar anacron.

Primero, asegúrate de que anacron esté instalado en tu sistema. En la mayoría de las distribuciones basadas en Debian/Ubuntu, puedes instalarlo con:.


sudo apt-get install anacron

Crear Directorios y Archivos de Configuración

anacron generalmente se configura a nivel de sistema, pero puedes configurarlo para un usuario común creando los directorios y archivos necesarios en tu directorio de inicio.

Crear Directorios:

Crea un directorio ~/.anacron para almacenar los archivos de estado de anacron:



mkdir -p ~/.anacron

Crear el Archivo de Tareas:

Crea un archivo llamado anacrontab en tu directorio de inicio:



touch ~/.anacron/anacrontab

Luego, edita este archivo con tu editor de texto preferido y añade la configuración de la tarea. Por ejemplo, para ejecutar el script de limpieza con BleachBit diariamente:


# archivo de configuración para anacron
# formato: periodo   demora   identificador   comando
# Trabajo diario
1       5       clean_with_bleachbit   /usr/local/bin/clean_with_bleachbit.sh >> /var/log/bleachbit.log 2>&1 && echo "---- $(date) ----" >> /var/log/bleachbit.log

Este ejemplo configura anacron para ejecutar el script clean_with_bleachbit.sh diariamente.

  • 1: Especifica que el trabajo debe ejecutarse diariamente.
  • 5 clean_with_bleachbit: Esto significa que el trabajo se ejecutará 5 minuto después de que anacron se inicie.
  • /usr/local/bin/clean_with_bleachbit.sh: Es el script que se va a ejecutar.
  • >> /var/log/bleachbit.log: Redirige la salida estándar (stdout) del script al archivo /var/log/bleachbit.log. El operador >> añade la salida al final del archivo sin sobrescribirlo.
  • 2>&1: Redirige la salida de error estándar (stderr) al mismo lugar que la salida estándar (stdout).

Desglose de 2>&1

  • 2 representa el descriptor de archivo para stderr.
  • > es el operador de redirección.
  • &1 significa que stderr se redirigirá al mismo lugar que stdout.

Crear un Script para Ejecutar anacron

Para asegurarte de que anacron se ejecute regularmente, incluso si el equipo se apaga, puedes crear un script que ejecute anacron cada vez que inicies sesión o se inicie el entorno de escritorio.

Crear el Script:

Crea un archivo llamado run_anacron.sh en tu directorio de inicio:



touch ~/run_anacron.sh

Luego, edita este archivo y añade lo siguiente:


#!/bin/bash

# Esperar 1 minuto para asegurar que el entorno esté listo
sleep 60

# Registro adicional para depuración
echo "Running Anacron script at $(date)" > ~/anacron_debug.log
echo "Current user: $(whoami)" >> ~/anacron_debug.log
echo "Current directory: $(pwd)" >> ~/anacron_debug.log
echo "Environment variables: $(env)" >> ~/anacron_debug.log
echo "Anacron status before execution:" >> ~/anacron_debug.log
/sbin/anacron -T -t ~/.anacron/anacrontab >> ~/anacron_debug.log 2>&1

# Ejecutar Anacron
/sbin/anacron -t ~/.anacron/anacrontab -S ~/.anacron -s
exit_code=$?

# Verificar el código de salida y registrar en el log
if [ $exit_code -eq 0 ]; then
    echo "Starting Anacron at $(date)" > ~/anacron_log.log
else
    echo "Anacron failed to start at $(date) with exit code $exit_code" > ~/anacron_log.log
fi

# Registrar el estado después de la ejecución
echo "Anacron status after execution:" >> ~/anacron_debug.log
/sbin/anacron -T -t ~/.anacron/anacrontab >> ~/anacron_debug.log 2>&1

Ejecutar anacron al Iniciar Sesión

Finalmente, configura tu entorno para ejecutar anacron al iniciar sesión. Puedes agregar el script run_anacron.sh a tus aplicaciones de inicio.

Para GNOME, por ejemplo:

  • Abre "Aplicaciones de inicio" (Startup Applications).
  • Añade una nueva entrada: Nombre: anacron
  • Comando: /home/tu_usuario/run_anacron.sh
    Comentario: Ejecutar tareas de anacron
  • Resumen: Siguiendo estos pasos, puedes usar anacron con un usuario común para ejecutar tareas programadas, asegurándote de que se ejecuten incluso si el equipo estuvo apagado durante el tiempo programado.

Además de estas variantes predefinidas, puedes definir tareas usando un formato más detallado, especificando el número de días entre ejecuciones. Aquí tienes algunos ejemplos adicionales:

Variantes de anacron

  • Especificar el Número de Días
    • Puedes especificar cualquier número de días entre ejecuciones.
    • Formato: [número de días] [demora en minutos] [identificador] [comando]
    • Ejemplo para ejecutar cada 3 días:
      
              
      3 1 clean_with_bleachbit /usr/local/bin/clean_with_bleachbit.sh >> /var/log/bleachbit.log 2>&1
              
              

Ejemplos Adicionales

  • Ejecutar Cada 2 Días:
    
        
    2 1 clean_temp_files /usr/local/bin/clean_temp_files.sh >> /var/log/clean_temp_files.log 2>&1
        
        
  • Ejecutar Cada 10 Días:
    
        
    10 1 backup_data /usr/local/bin/backup_data.sh >> /var/log/backup_data.log 2>&1
        
        

Sintaxis del Archivo anacrontab

Cada línea en el archivo anacrontab sigue esta sintaxis:

[periodo] [demora en minutos] [identificador] [comando]
  • periodo: Número de días entre ejecuciones.
  • demora en minutos: Tiempo de espera antes de ejecutar la tarea después de iniciar anacron.
  • identificador: Un nombre único para identificar la tarea.
  • comando: El comando o script a ejecutar.

Archivo ~/.anacron/anacrontab con Varias Tareas


# archivo de configuración para anacron
# formato: periodo   demora   identificador   comando
# Trabajo diario
1       5       clean_with_bleachbit   /usr/local/bin/clean_with_bleachbit.sh >> /var/log/bleachbit.log 2>&1
# Trabajo semanal
7       1       clean_logs             /usr/local/bin/clean_logs.sh >> /var/log/clean_logs.log 2>&1
# Trabajo mensual
30      30      system_backup          /usr/local/bin/system_backup.sh >> /var/log/system_backup.log 2>&1
# Otros trabajos
3       1       clean_temp_files       /usr/local/bin/clean_temp_files.sh >> /var/log/clean_temp_files.log 2>&1
10      1       backup_data            /usr/local/bin/backup_data.sh >> /var/log/backup_data.log 2>&1

Estas configuraciones permiten una gran flexibilidad en la programación de tareas periódicas, asegurando que se ejecuten incluso si el sistema no está encendido en el momento exacto programado.

martes, 11 de junio de 2024

Automatización de Marcas de Agua en Imágenes y Clasificación Basada en Luminosidad

Por Julio Alberto Lascano

En esta entrada, exploraremos dos scripts útiles para la manipulación de imágenes: uno para aplicar una marca de agua y otro para clasificar imágenes según sus características. Ambos scripts son herramientas valiosas para fotógrafos, diseñadores gráficos y cualquier persona que trabaje con imágenes digitales. La combinación de Bash y Python permite crear una solución eficiente y automatizada para procesar múltiples imágenes a la vez.

Introducción a las Librerías cv2 (OpenCV) y NumPy

En el mundo de la programación y la informática, existen herramientas poderosas que nos permiten realizar tareas complejas de manera más sencilla y eficiente. Hoy, vamos a explorar dos de estas herramientas: cv2 (también conocida como OpenCV) y NumPy.

¿Qué es cv2 (OpenCV)?

OpenCV (Open Source Computer Vision Library) es una biblioteca de software de visión por computadora. Esto significa que proporciona una gran cantidad de funciones que permiten a las computadoras "ver" y procesar imágenes y videos. Con OpenCV, puedes realizar tareas como:

  • Detectar y reconocer caras en imágenes.
  • Seguir objetos en movimiento en videos.
  • Aplicar filtros y efectos a imágenes.
  • Medir distancias y tamaños en fotografías.
Detectar y reconocer caras en imágenes


La librería cv2 es simplemente el módulo de Python para usar OpenCV. Es una herramienta muy potente en el campo de la inteligencia artificial y la visión por computadora.

¿Qué es NumPy?

NumPy (Numerical Python) es una biblioteca para el lenguaje de programación Python que permite realizar operaciones matemáticas y estadísticas de manera eficiente. Es especialmente útil cuando trabajamos con grandes cantidades de datos, ya que está diseñada para realizar cálculos rápidos y precisos. Con NumPy, puedes:

  • Crear y manipular arreglos (matrices) de datos.
  • Realizar operaciones matemáticas complejas.
  • Procesar datos de manera eficiente.
  • Integrar con otras librerías científicas y de análisis de datos.

NumPy es la base para muchas otras librerías científicas y de aprendizaje automático en Python, como SciPy, Pandas y TensorFlow.

NumPy - Software de análisis numérico

¿Por qué Usar cv2 y NumPy Juntas?

La combinación de cv2 y NumPy es muy común en proyectos de visión por computadora. NumPy se utiliza para manejar y procesar los datos de las imágenes (que son, en esencia, matrices de números) de manera eficiente, mientras que cv2 proporciona las herramientas específicas para la visión por computadora. Juntas, estas librerías permiten desarrollar aplicaciones poderosas que pueden analizar y manipular imágenes y videos de maneras muy avanzadas.

Descripción de los Scripts

aplicar_marca_agua.sh

Este script de Bash automatiza el proceso de aplicar una marca de agua a todas las imágenes en un directorio especificado. Utiliza las potentes herramientas de ImageMagick para realizar esta tarea de manera eficiente. A continuación, se detalla el flujo de trabajo del script:

  • Verificación de comandos de ImageMagick: Se asegura de que los comandos 'identify', 'convert' y 'composite' estén disponibles.
  • Definición de parámetros: Se especifican las rutas de las marcas de agua (blanca y negra), el directorio de imágenes a procesar, el factor de escala para el tamaño de la marca de agua y el directorio de salida.
  • Verificación de parámetros y rutas: Se comprueba que todos los parámetros necesarios se han proporcionado y que las rutas de las marcas de agua y el directorio de imágenes existen. Si el directorio de salida no existe, se crea automáticamente.
  • Bucle para procesar cada imagen: Itera sobre cada archivo en el directorio de imágenes, verificando si es una imagen válida.
  • Obtención del tamaño de la imagen: Utiliza el comando 'identify' para obtener el tamaño de la imagen en píxeles.
  • Cálculo del tamaño de la marca de agua: Calcula el tamaño de la marca de agua proporcional al tamaño de la imagen original.
  • Redimensionamiento de la marca de agua: Redimensiona la marca de agua al tamaño calculado.
  • Aplicación de la marca de agua: Aplica la marca de agua al pie de la imagen con un margen inferior centrado.
  • Eliminación de archivos temporales: Elimina el archivo temporal de la marca de agua redimensionada después de aplicarla a la imagen.

clasificar_imagen_v5.py

Este script de Python se utiliza para determinar el color (blanco o negro) más adecuado para la marca de agua en función de la luminosidad de la región inferior de la imagen. Utiliza las bibliotecas OpenCV (cv2) y NumPy, que son herramientas poderosas para la visión por computadora y la manipulación de matrices numéricas.

  • OpenCV (cv2): Es una biblioteca popular de código abierto para visión por computadora y procesamiento de imágenes. Proporciona una amplia gama de funciones para manipular y analizar imágenes.
  • NumPy: Es una biblioteca fundamental en Python para la computación científica y numérica. Proporciona un objeto de matriz multidimensional y una variedad de funciones para operar sobre estas matrices.

Cómo Funciona

El script de Python realiza una segmentación basada en color en la región inferior de la imagen para identificar ciertos tonos o rangos de color. Luego, calcula la luminosidad promedio de esta región y decide si la marca de agua debe ser blanca o negra basándose en la luminosidad calculada.

Pasos del Proceso

  • Carga de la imagen: El script carga la imagen proporcionada como argumento.
  • Definición de la región inferior: Se define una región en la parte inferior de la imagen, que es donde se aplicará la marca de agua.
  • Segmentación basada en color: Se segmenta la región inferior para identificar ciertos tonos de color.
  • Cálculo de la luminosidad promedio: Se calcula la luminosidad promedio de la región inferior y de la región donde se detecta un color específico.
  • Decisión del color de la marca de agua: Basándose en la luminosidad promedio y la presencia de un color específico, el script decide si la marca de agua debe ser blanca o negra.

Este enfoque asegura que la marca de agua se vea correctamente en la imagen, proporcionando un buen contraste independientemente de la luminosidad de la región donde se aplica.

Descripción del Script: aplicar_marca_agua.sh

El script aplicar_marca_agua.sh automatiza el proceso de aplicar una marca de agua a todas las imágenes en un directorio especificado. A continuación, se explica paso a paso lo que hace el script:

  1. Verificación de comandos de ImageMagick: Se verifica si los comandos 'identify', 'convert' y 'composite' están disponibles.
  2. Definición de parámetros:
    • MARCA_DE_AGUA_BLANCA: Ruta de la imagen que se utilizará como marca de agua blanca.
    • MARCA_DE_AGUA_NEGRA: Ruta de la imagen que se utilizará como marca de agua negra.
    • DIRECTORIO_IMAGENES: Directorio que contiene las imágenes a las que se aplicará la marca de agua.
    • FACTOR_ESCALA: Factor de escala que determina el tamaño proporcional de la marca de agua en relación con el ancho de la imagen original.
    • DIRECTORIO_SALIDA: Directorio donde se guardarán las imágenes con la marca de agua aplicada.
  3. Verificación de parámetros y rutas:
    • Se verifica que todos los parámetros necesarios se han proporcionado.
    • Se verifica que las rutas de las marcas de agua y el directorio de imágenes existen.
    • Si el directorio de salida no existe, se crea automáticamente.
  4. Bucle para procesar cada imagen: Se utiliza un bucle 'for' para iterar sobre cada archivo en el directorio de imágenes especificado.
  5. Obtención del tamaño de la imagen: Se utiliza el comando 'identify' para obtener el tamaño de la imagen en píxeles.
  6. Cálculo del tamaño de la marca de agua: Se calcula el tamaño de la marca de agua proporcional al tamaño de la imagen original, utilizando el factor de escala definido.
  7. Redimensionamiento de la marca de agua: Se redimensiona la marca de agua al tamaño calculado y se elimina cualquier perfil de color incrustado para evitar advertencias.
  8. Aplicación de la marca de agua: Se aplica la marca de agua al pie de la imagen con un margen inferior centrado utilizando el comando 'composite'.
  9. Eliminación de archivos temporales: Se elimina el archivo temporal de la marca de agua redimensionada después de aplicarla a la imagen.
 
#!/bin/bash

# --------------------------------------------------------------------------------------------------------------------------------------
# File: aplicar_marca_agua.sh
# By Julio Alberto Lascano http://drcalambre.blogspot.com/
#________          _________        .__                ___.                  
#\______ \_______  \_   ___ \_____  |  | _____    _____\_ |_________   ____  
# |    |  \_  __ \ /    \  \/\__  \ |  | \__  \  /     \| __ \_  __ \_/ __ \ 
# |    `   \  | \/ \     \____/ __ \|  |__/ __ \|  Y Y  \ \_\ \  | \/\  ___/ 
#/_______  /__|     \______  (____  /____(____  /__|_|  /___  /__|    \___  >
#        \/                \/     \/          \/      \/    \/            \/ 
# --------------------------------------------------------------------------------------------------------------------------------------
# Last modified:2024-06-10
# --------------------------------------------------------------------------------------------------------------------------------------
# Descripción del script: aplicar_marca_agua.sh
# --------------------------------------------------------------------------------------------------------------------------------------
# Uso: aplicar_marca_agua.sh -b [marca_agua_blanca] -n [marca_agua_negra] -d [directorio_imagenes] -s [factor_escala] -o [directorio_salida]
# --------------------------------------------------------------------------------------------------------------------------------------
# Este script automatiza el proceso de aplicar una marca de agua a todas las imágenes en un directorio especificado.
# A continuación se explica paso a paso lo que hace el script:
#
# 1. Verificación de comandos de ImageMagick:
#    - Se verifica si los comandos 'identify', 'convert' y 'composite' están disponibles.
#
# 2. Definición de parámetros:
#    - MARCA_DE_AGUA_BLANCA: Ruta de la imagen que se utilizará como marca de agua blanca.
#    - MARCA_DE_AGUA_NEGRA: Ruta de la imagen que se utilizará como marca de agua negra.
#    - DIRECTORIO_IMAGENES: Directorio que contiene las imágenes a las que se aplicará la marca de agua.
#    - FACTOR_ESCALA: Factor de escala que determina el tamaño proporcional de la marca de agua en relación con el ancho de la imagen original.
#    - DIRECTORIO_SALIDA: Directorio donde se guardarán las imágenes con la marca de agua aplicada.
#
# 3. Verificación de parámetros y rutas:
#    - Se verifica que todos los parámetros necesarios se han proporcionado.
#    - Se verifica que las rutas de las marcas de agua y el directorio de imágenes existen.
#    - Si el directorio de salida no existe, se crea automáticamente.
#
# 4. Bucle para procesar cada imagen:
#    - Se utiliza un bucle 'for' para iterar sobre cada archivo en el directorio de imágenes especificado.
#    - Se verifica si el archivo actual en el bucle es un archivo regular utilizando la condición 'if [ -f "$IMAGEN" ]'.
#
# 5. Obtención del tamaño de la imagen:
#    - Se utiliza el comando 'identify' para obtener el tamaño de la imagen en píxeles.
#
# 6. Cálculo del tamaño de la marca de agua:
#    - Se calcula el tamaño de la marca de agua proporcional al tamaño de la imagen original, utilizando el factor de escala definido.
#
# 7. Redimensionamiento de la marca de agua:
#    - Se redimensiona la marca de agua al tamaño calculado y se elimina cualquier perfil de color incrustado para evitar advertencias.
#
# 8. Aplicación de la marca de agua:
#    - Se aplica la marca de agua al pie de la imagen con un margen inferior centrado utilizando el comando 'composite'.
#
# 9. Eliminación de archivos temporales:
#    - Se elimina el archivo temporal de la marca de agua redimensionada después de aplicarla a la imagen.
# --------------------------------------------------------------------------------------------------------------------------------------


# Verificación de comandos de ImageMagick
if ! command -v identify &> /dev/null || ! command -v convert &> /dev/null || ! command -v composite &> /dev/null
then
    echo "ImageMagick no está instalado o los comandos necesarios no están disponibles. Por favor, instálalo antes de ejecutar este script."
    exit 1
fi

# Manejo de errores
# Se añade manejo de errores para asegurar que el script se detenga si ocurre algún problema. 
# Se hace con: set -e lo que hace que el script termine si algún comando falla.

set -e

# Uso: aplicar_marca_agua.sh -b [marca_agua_blanca] -n [marca_agua_negra] -d [directorio_imagenes] -s [factor_escala] -o [directorio_salida]
while getopts "b:n:d:s:o:" opt; do
    case ${opt} in
        b ) MARCA_DE_AGUA_BLANCA=$OPTARG ;;
        n ) MARCA_DE_AGUA_NEGRA=$OPTARG ;;
        d ) DIRECTORIO_IMAGENES=$OPTARG ;;
        s ) FACTOR_ESCALA=$OPTARG ;;
        o ) DIRECTORIO_SALIDA=$OPTARG ;;
        \? ) echo "Uso: aplicar_marca_agua.sh -b [marca_agua_blanca] -n [marca_agua_negra] -d [directorio_imagenes] -s [factor_escala] -o [directorio_salida]"
             exit 1 ;;
    esac
done

# Verificación de parámetros
if [ -z "$MARCA_DE_AGUA_BLANCA" ] || [ -z "$MARCA_DE_AGUA_NEGRA" ] || [ -z "$DIRECTORIO_IMAGENES" ] || [ -z "$FACTOR_ESCALA" ] || [ -z "$DIRECTORIO_SALIDA" ]; then
    echo ""
    echo "Uso: aplicar_marca_agua.sh -b [marca_agua_blanca] -n [marca_agua_negra] -d [directorio_imagenes] -s [factor_escala] -o [directorio_salida]"
    echo ""
    echo "Todos los parámetros (-b, -n, -d, -s, -o) son obligatorios."
    echo "-------------------------------------------------------------------------------------------------------------"
    echo "Factor de escala para el tamaño de la marca de agua -s [factor_escala]"
    echo "Por ejemplo: -s 0.15 , un factor de escala del 15% es adecuado para la fotografia de paisajes."
    echo "-------------------------------------------------------------------------------------------------------------"
    exit 1
fi

# Verificación de la existencia de las rutas de las marcas de agua
if [ ! -f "$MARCA_DE_AGUA_BLANCA" ]; then
    echo "La ruta de la marca de agua blanca ($MARCA_DE_AGUA_BLANCA) no existe."
    exit 1
fi

if [ ! -f "$MARCA_DE_AGUA_NEGRA" ]; then
    echo "La ruta de la marca de agua negra ($MARCA_DE_AGUA_NEGRA) no existe."
    exit 1
fi

# Verificación de la existencia del directorio de imágenes
if [ ! -d "$DIRECTORIO_IMAGENES" ]; then
    echo "El directorio de imágenes ($DIRECTORIO_IMAGENES) no existe."
    exit 1
fi

# Verificación de la existencia del directorio de salida
if [ ! -d "$DIRECTORIO_SALIDA" ]; then
    echo "El directorio de salida ($DIRECTORIO_SALIDA) no existe. Creando el directorio..."
    mkdir -p "$DIRECTORIO_SALIDA"
fi

# Obtener el directorio del script Bash
SCRIPT_DIR="$(dirname "$(realpath "${BASH_SOURCE[0]}")")"

# Ruta del script Python relativo al directorio del script Bash
SCRIPT_PATH="$SCRIPT_DIR/scripts/clasificar_imagen_v5.py"

# Verificar que el script Python exista
if [[ ! -f "$SCRIPT_PATH" ]]; then
  echo "El script $SCRIPT_PATH no existe. Verifica la ruta."
  exit 1
fi

contador=0
tiempo_inicio=$(date +%s)

# Aplicar marca de agua a cada imagen en el directorio
for IMAGEN in "$DIRECTORIO_IMAGENES"/*; do
    if [ -f "$IMAGEN" ] && file --mime-type "$IMAGEN" | grep -q -E "image/(png|gif|jpeg|jpg)"; then
        nombre_imagen=$(basename "$IMAGEN")
        
        # La expresión ${nombre_imagen##*.} utiliza un mecanismo de expansión de parámetros en el shell 
        # de Unix para extraer la extensión de un nombre de archivo.
        # Significa eliminar todo hasta el último punto en el nombre del archivo, y devolver lo que queda.
        
        
        extension_imagen="${nombre_imagen##*.}"
        
        # Obtener el tamaño de la imagen (ancho x altura)
        tamano_imagen=$(identify -format "%wx%h" "$IMAGEN")
        
        # Separar el ancho y la altura
        ancho_imagen=$(echo "$tamano_imagen" | cut -d'x' -f 1)
        altura_imagen=$(echo "$tamano_imagen" | cut -d'x' -f 2)
        
        # Calcular el tamaño de la marca de agua proporcional al tamaño de la imagen
        tamano_marca=$(echo "$ancho_imagen * $FACTOR_ESCALA" | bc)
        
        # Llamada al script de Python para determinar el color (blanco o negro)
        resultados=$(python "$SCRIPT_PATH" "$DIRECTORIO_IMAGENES$nombre_imagen" "$FACTOR_ESCALA")
        
        # Imprimir los resultados
        
        # Leer los resultados separados
		read -r resultado_color luminosidad <<< "$resultados"
		        
        # Imprimir el resultado capturado para depuración
        
		echo "-------------------------------"
		echo "Color marca de agua: $resultado_color"
		echo "Luminosidad: $luminosidad"
		echo "-------------------------------"
		echo "Aplicando marca de agua a $DIRECTORIO_IMAGENES$nombre_imagen -> $DIRECTORIO_SALIDA${nombre_imagen%.*}_wm.$extension_imagen"

        # Seleccionar la marca de agua según el color determinado
        case "$resultado_color" in
            "blanco")
                MARCA_DE_AGUA=$MARCA_DE_AGUA_BLANCA
                ;;
            "negro")
                MARCA_DE_AGUA=$MARCA_DE_AGUA_NEGRA
                ;;
            *)
                echo "Color desconocido: $color. Usando la marca de agua blanca por defecto."
                MARCA_DE_AGUA=$MARCA_DE_AGUA_BLANCA
                ;;
        esac
        
     
        # Redimensionar la marca de agua al tamaño calculado y eliminar el perfil de color
        # Crear un archivo temporal
        marca_de_agua_redimensionada=$(mktemp)
        convert "$MARCA_DE_AGUA" -resize "${tamano_marca}x${tamano_marca}" -strip "$marca_de_agua_redimensionada"
        
        # Aplicar marca de agua al pie de la imagen con margen inferior centrado
        composite -dissolve 50% -gravity South -geometry +0+50   "$marca_de_agua_redimensionada" "$IMAGEN" "$DIRECTORIO_SALIDA/${nombre_imagen%.*}_wm.$extension_imagen"
        
        # Eliminar el archivo temporal de la marca de agua redimensionada
        rm "$marca_de_agua_redimensionada"
        
        # Incrementar el contador por cada imagen procesada
		contador=$((contador + 1))
        
    fi
done

# Calcular el tiempo total transcurrido
tiempo_fin=$(date +%s)
tiempo_total=$((tiempo_fin - tiempo_inicio))

# Convertir tiempo total a formato hh:mm:ss
horas=$((tiempo_total / 3600))
minutos=$(( (tiempo_total % 3600) / 60 ))
segundos=$((tiempo_total % 60))

# Mostrar el total de imágenes procesadas y el tiempo que tomó
echo "Total de imágenes procesadas: $contador"
# Formatear la salida
printf "Tiempo total transcurrido: %02d:%02d:%02d\n" $horas $minutos $segundos


Descripción del Script: clasificar_imagen_v5.py

El script clasificar_imagen_v5.py carga la imagen y define la región inferior de la misma para segmentación basada en color y análisis de luminosidad promedio. A continuación, se detallan las funcionalidades del script:

  1. Segmentación basada en color en la región inferior:
    • Identifica ciertos tonos o rangos de color en la región inferior de la imagen.
  2. Cálculo de la luminosidad promedio:
    • Calcula la luminosidad promedio de la región inferior y de la región donde se detecta un color específico.
    • Basándose en la luminosidad promedio y la presencia de color específico, decide si la marca de agua debe ser blanca o negra.
  3. Bibliotecas utilizadas:
    • cv2 (OpenCV): Biblioteca popular para la visión por computadora y el procesamiento de imágenes.
    • NumPy: Biblioteca fundamental para computación científica y numérica en Python.

El script imprime el resultado (blanco o negro) junto con la luminosidad promedio de la región inferior.

 
#!/usr/bin/env python

# --------------------------------------------------------------------------------------------------------------------------------------
# File: clasificar_imagen_v5.py
# By Julio Alberto Lascano http://drcalambre.blogspot.com/
#________          _________        .__                ___.                  
#\______ \_______  \_   ___ \_____  |  | _____    _____\_ |_________   ____  
# |    |  \_  __ \ /    \  \/\__  \ |  | \__  \  /     \| __ \_  __ \_/ __ \ 
# |    `   \  | \/ \     \____/ __ \|  |__/ __ \|  Y Y  \ \_\ \  | \/\  ___/ 
#/_______  /__|     \______  (____  /____(____  /__|_|  /___  /__|    \___  >
#        \/                \/     \/          \/      \/    \/            \/ 
# --------------------------------------------------------------------------------------------------------------------------------------
# Last modified:2024-05-30
# --------------------------------------------------------------------------------------------------------------------------------------
# Descripción del script: clasificar_imagen_v5.py
# Carga la imagen y define la región inferior de la misma.
# --------------------------------------------------------------------------------------------------------------------------------------
# Segmentación basada en color en la región inferior y luminosidad promedio de la región inferior:
# --------------------------------------------------------------------------------------------------------------------------------------
# Realiza una segmentación basada en color en la región inferior para identificar ciertos tonos o rangos de color.
# Calcula la luminosidad promedio de la región inferior y de la región donde se detecta un color específico.
# Basándose en la luminosidad promedio y la presencia de color específico, decide si la marca de agua debe ser blanca o negra.
# Imprime el resultado (blanco o negro) junto con la luminosidad promedio de la región inferior.
# --------------------------------------------------------------------------------------------------------------------------------------
# cv2
# --------------------------------------------------------------------------------------------------------------------------------------
# La biblioteca cv2, o OpenCV (Open Source Computer Vision Library), es una biblioteca popular de código abierto diseñada para 
# la visión por computadora y el procesamiento de imágenes. Ofrece una amplia gama de funciones y algoritmos que permiten realizar 
# una variedad de tareas relacionadas con el procesamiento de imágenes y la visión por computadora.
# --------------------------------------------------------------------------------------------------------------------------------------
# NumPy
# --------------------------------------------------------------------------------------------------------------------------------------
# NumPy es una biblioteca fundamental en Python para computación científica y numérica. Proporciona un objeto de matriz 
# multidimensional, junto con una variedad de funciones para operar en estas matrices.
# NumPy se utiliza específicamente para calcular la media (np.mean) y la desviación estándar (np.std) de la luminosidad del color detectado
# en la región inferior de la imagen. Estas estadísticas se utilizan luego para ajustar dinámicamente el valor del umbral para decidir si 
# aplicar una marca de agua blanca o negra.
# --------------------------------------------------------------------------------------------------------------------------------------


import sys
import cv2
import numpy as np

# Función para calcular la luminosidad promedio de una región de la imagen
def calcular_luminosidad_promedio(region):
    luminosidad = cv2.mean(region)[0]
    return luminosidad

def main():
    # Verificar que se proporcionen los argumentos necesarios
    if len(sys.argv) < 3:
        print("Uso: clasificar_imagen_v5.py  ")
        sys.exit(1)

    # Ruta de la imagen proporcionada como argumento
    ruta_imagen = sys.argv[1]

    # Definir el factor de escala proporcionado como argumento
    try:
        FACTOR_ESCALA = float(sys.argv[2])
    except ValueError:
        print("El factor de escala debe ser un número.")
        sys.exit(1)

    # Cargar la imagen
    img = cv2.imread(ruta_imagen)

    # Verificar si la imagen se cargó correctamente
    if img is None:
        print("Error al cargar la imagen. Verifique la ruta y el formato del archivo.")
        sys.exit(1)

    # Obtener dimensiones de la imagen
    alto, ancho, _ = img.shape

    # Calcular el tamaño del cuadrante a analizar
    #
    # FACTOR_ESCALA se usa para determinar el tamaño del cuadrante a analizar en la imagen. Ese cuadrante es el que ocupara la marca de agua.
    # alto_cuadrante y ancho_cuadrante se calculan como una fracción de las dimensiones de la imagen.
    #
    # Región Inferior Centrada:
    # Las coordenadas (y_inicio, x_inicio) se calculan para centrar el cuadrante horizontalmente y posicionarlo en la parte inferior de la imagen.
    #
    # Segmentación y Análisis:
    # La segmentación basada en color y el cálculo de luminosidad promedio se realizan en esta región inferior centrada.
    # Esto asegura que el análisis se realice en la parte de la imagen donde estará la marca de agua, considerando su posición centrada y tamaño relativo basado en el factor de escala.

    alto_cuadrante = int(alto * FACTOR_ESCALA * 2)
    ancho_cuadrante = int(ancho * FACTOR_ESCALA * 2)

    # Definir las coordenadas del cuadrante inferior centrado
    y_inicio = alto - alto_cuadrante  # Inicio del cuadrante inferior
    x_inicio = (ancho - ancho_cuadrante) // 2  # Centrar horizontalmente

    # Extraer el cuadrante inferior centrado de la imagen
    region_inferior = img[y_inicio:, x_inicio:x_inicio + ancho_cuadrante]

    # Segmentación basada en color en la región inferior de la imagen
    region_inferior_hsv = cv2.cvtColor(region_inferior, cv2.COLOR_BGR2HSV)
    lower_color = (0, 50, 50)  # Define el rango inferior de color HSV
    upper_color = (20, 255, 255)  # Define el rango superior de color HSV
    mask_color = cv2.inRange(region_inferior_hsv, lower_color, upper_color)

    # Calcular la luminosidad promedio del color detectado en la región inferior
    luminosidad_color = calcular_luminosidad_promedio(mask_color)

    # Calcular estadísticas sobre la luminosidad promedio del color
    luminosidad_color_mean = np.mean(luminosidad_color)
    luminosidad_color_std = np.std(luminosidad_color)

    # Ajustar dinámicamente el valor de umbral_color
    umbral_color = luminosidad_color_mean + 2 * luminosidad_color_std  # Por ejemplo, media + 2 * desviación estándar

    # Calcular la luminosidad promedio de la región inferior
    luminosidad_region_inferior = calcular_luminosidad_promedio(region_inferior)

    # Decidir el color de la marca de agua basado en la luminosidad promedio y el umbral dinámico
    
    # El valor de 127 se utiliza como umbral de luminosidad. Este valor se elige arbitrariamente como punto de corte 
    # para distinguir entre regiones relativamente oscuras y regiones relativamente claras en la imagen. 
    # Un valor de 127 corresponde aproximadamente a la mitad del rango de 0 a 255 en el espacio de color de escala de grises, 
    # donde 0 representa el negro absoluto y 255 representa el blanco absoluto.
    # Si la luminosidad promedio de la región inferior es menor o igual a 127, se considera que esta región es relativamente 
    # oscura. En este caso, se asume que una marca de agua blanca sería más visible y contrastaría mejor con el fondo oscuro. 
    # Por lo tanto, se decide aplicar una marca de agua blanca.
    #
    # La variable luminosidad_color_mean contiene la luminosidad promedio del color detectado en la región inferior de la imagen. 
    # Esta región se segmenta en función de ciertos tonos o rangos de color específicos, como se especifica en el código.
    #
    # Umbral dinámicamente ajustado (umbral_color): En lugar de utilizar un umbral estático, como en el caso 
    # de luminosidad_region_inferior <= 127, aquí se calcula y utiliza un umbral dinámico basado en las estadísticas de la 
    # luminosidad del color detectado en la región inferior. Este umbral puede ajustarse según las características específicas de 
    # la imagen en términos de iluminación, tonos de color, etc.
    #
    # Decisión de aplicar marca de agua blanca o negra: Si la luminosidad promedio del color detectado en la región inferior es menor 
    # o igual al umbral dinámicamente ajustado (umbral_color), se considera que esta región es relativamente oscura en términos de color. 
    # En este caso, se asume que una marca de agua blanca sería más visible y contrastaría mejor con el fondo oscuro. 
    # Por lo tanto, se decide aplicar una marca de agua blanca.
    #
    # Adaptabilidad del umbral dinámico: Al calcular el umbral dinámicamente en función de las estadísticas de la luminosidad del color 
    # detectado, se mejora la adaptabilidad del proceso de decisión a diferentes condiciones de iluminación y variaciones en los tonos de
    # color de la imagen.
    
    if luminosidad_region_inferior <= 127 and luminosidad_color_mean <= umbral_color:
        resultado_color = "blanco"
    else:
        resultado_color = "negro"

    # Imprimir el resultado y la luminosidad
    print(resultado_color, luminosidad_region_inferior)

if __name__ == "__main__":
    main()


Uso de la Desviación Estándar

La desviación estándar mide qué tan dispersos están los valores de luminosidad. Si todos los valores son muy similares, la desviación estándar será baja; si hay mucha variación, será alta.

Se calcula un "umbral" dinámico usando la desviación estándar. Este umbral es una combinación de la luminosidad promedio del color y la desviación estándar de esa luminosidad.

Conclusión

La combinación de estos dos scripts proporciona una solución robusta y eficiente para aplicar marcas de agua a un gran número de imágenes de manera automatizada. Utilizando Bash y Python, se puede asegurar que cada imagen reciba una marca de agua que se ajuste perfectamente a sus características específicas, mejorando así la presentación y protección de sus imágenes digitales.

Dependencias

- **Imagemagick**:Paquete de software para manipular y editar imágenes.

- **bc**: es una calculadora de precisión arbitraria en Unix-like.

- **OpenCV (`cv2`)**: una popular biblioteca de código abierto diseñada para visión por computadora y procesamiento de imágenes.

- **NumPy**: Biblioteca fundamental en Python para computación científica y numérica. Se utiliza para calcular estadísticas como la media y la desviación estándar de la luminosidad para la detección de color en la región inferior de la imagen.

 
antix1@antix1:~ sudo apt-get install imagemagick bc
antix1@antix1:~ sudo apt-get install python3-opencv
antix1@antix1:~ sudo apt-get install python3-numpy

Los escript se pueden descargar desde mi repositorio en GitHub:

https://github.com/DrCalambre/watermark 

Entradas relacionadas tambien en este blog:

Como crear una Marca de Agua con GIMP.



lunes, 27 de mayo de 2024

Protege tus Fotos con Facilidad: Cómo Añadir Marcas de Agua Usando Bash con antiX

 En el mundo digital de hoy, proteger tus imágenes es más importante que nunca. Con el aumento del contenido en línea, es crucial garantizar que tu trabajo esté protegido contra el uso no autorizado. Una forma efectiva de hacerlo es mediante la aplicación de marcas de agua a tus imágenes.


marca_agua_graciela_sanz_color_blanco.png

Pero, ¿qué ocurre cuando tienes cientos, o incluso miles de imágenes que necesitan ser protegidas? Ahí es donde entra en juego la automatización.

Con el siguiente script en bash, simplificamos el proceso de aplicación de marcas de agua a gran escala. Veamos cómo funciona.

El script recorre cada imagen en el directorio especificado, obteniendo su tamaño y calculando automáticamente el tamaño proporcional de la marca de agua.


Fotografía con marca de agua

Luego, redimensiona la marca de agua para que se ajuste perfectamente a cada imagen, eliminando cualquier perfil de color incrustado para garantizar una aplicación limpia y consistente.

Finalmente, aplica la marca de agua al pie de cada imagen, con un margen inferior centrado para una presentación elegante y profesional.

Con este proceso automatizado, puedes proteger tus imágenes de manera eficiente y confiable, manteniendo tu trabajo seguro y protegido en todo momento.


Fotografía con marca de agua

 
#!/bin/bash

# --------------------------------------------------------------------------------------------------------------------------------------
# File: aplicar_marca_agua.sh
# By Julio Alberto Lascano http://drcalambre.blogspot.com/
#________          _________        .__                ___.                  
#\______ \_______  \_   ___ \_____  |  | _____    _____\_ |_________   ____  
# |    |  \_  __ \ /    \  \/\__  \ |  | \__  \  /     \| __ \_  __ \_/ __ \ 
# |    `   \  | \/ \     \____/ __ \|  |__/ __ \|  Y Y  \ \_\ \  | \/\  ___/ 
#/_______  /__|     \______  (____  /____(____  /__|_|  /___  /__|    \___  >
#        \/                \/     \/          \/      \/    \/            \/ 
# --------------------------------------------------------------------------------------------------------------------------------------
# Last modified:2024-05-28
# --------------------------------------------------------------------------------------------------------------------------------------
# Descripción del script: aplicar_marca_agua.sh
# --------------------------------------------------------------------------------------------------------------------------------------
# Uso: aplicar_marca_agua.sh -m [marca_agua] -d [directorio_imagenes] -s [factor_escala] -o [directorio_salida]
# --------------------------------------------------------------------------------------------------------------------------------------
# Este script automatiza el proceso de aplicar una marca de agua a todas las imágenes en un directorio especificado.
# A continuación se explica paso a paso lo que hace el script:
#
# 1. Verificación de comandos de ImageMagick:
#    - Se verifica si los comandos 'identify', 'convert' y 'composite' están disponibles.
#
# 2. Definición de parámetros:
#    - MARCA_DE_AGUA: Ruta de la imagen que se utilizará como marca de agua.
#    - DIRECTORIO_IMAGENES: Directorio que contiene las imágenes a las que se aplicará la marca de agua.
#    - FACTOR_ESCALA: Factor de escala que determina el tamaño proporcional de la marca de agua en relación con el ancho de la imagen original.
#    - DIRECTORIO_SALIDA: Directorio donde se guardarán las imágenes con la marca de agua aplicada.
#
# 3. Verificación de parámetros y rutas:
#    - Se verifica que todos los parámetros necesarios se han proporcionado.
#    - Se verifica que la ruta de la marca de agua y el directorio de imágenes existen.
#    - Si el directorio de salida no existe, se crea automáticamente.
#
# 4. Bucle para procesar cada imagen:
#    - Se utiliza un bucle 'for' para iterar sobre cada archivo en el directorio de imágenes especificado.
#    - Se verifica si el archivo actual en el bucle es un archivo regular utilizando la condición 'if [ -f "$IMAGEN" ]'.
#
# 5. Obtención del tamaño de la imagen:
#    - Se utiliza el comando 'identify' para obtener el tamaño de la imagen en píxeles.
#
# 6. Cálculo del tamaño de la marca de agua:
#    - Se calcula el tamaño de la marca de agua proporcional al tamaño de la imagen original, utilizando el factor de escala definido.
#
# 7. Redimensionamiento de la marca de agua:
#    - Se redimensiona la marca de agua al tamaño calculado y se elimina cualquier perfil de color incrustado para evitar advertencias.
#
# 8. Aplicación de la marca de agua:
#    - Se aplica la marca de agua al pie de la imagen con un margen inferior centrado utilizando el comando 'composite'.
#
# 9. Eliminación de archivos temporales:
#    - Se elimina el archivo temporal de la marca de agua redimensionada después de aplicarla a la imagen.
# --------------------------------------------------------------------------------------------------------------------------------------


# Verificación de comandos de ImageMagick
if ! command -v identify &> /dev/null || ! command -v convert &> /dev/null || ! command -v composite &> /dev/null
then
    echo "ImageMagick no está instalado o los comandos necesarios no están disponibles. Por favor, instálalo antes de ejecutar este script."
    exit 1
fi

# Manejo de errores
# Se añade manejo de errores para asegurar que el script se detenga si ocurre algún problema. 
# Se hace con: set -e lo que hace que el script termine si algún comando falla.

set -e

# Uso: aplicar_marca_agua.sh -m [marca_agua] -d [directorio_imagenes] -s [factor_escala] -o [directorio_salida]
while getopts "m:d:s:o:" opt; do
    case ${opt} in
        m ) MARCA_DE_AGUA=$OPTARG ;;
        d ) DIRECTORIO_IMAGENES=$OPTARG ;;
        s ) FACTOR_ESCALA=$OPTARG ;;
        o ) DIRECTORIO_SALIDA=$OPTARG ;;
        \? ) echo "Uso: aplicar_marca_agua.sh -m [marca_agua] -d [directorio_imagenes] -s [factor_escala] -o [directorio_salida]"
             exit 1 ;;
    esac
done

# Verificación de parámetros
if [ -z "$MARCA_DE_AGUA" ] || [ -z "$DIRECTORIO_IMAGENES" ] || [ -z "$FACTOR_ESCALA" ] || [ -z "$DIRECTORIO_SALIDA" ]; then
    echo ""
    echo "Uso: aplicar_marca_agua.sh -m [marca_agua] -d [directorio_imagenes] -s [factor_escala] -o [directorio_salida]"
    echo ""
    echo "Todos los parámetros (-m, -d, -s, -o) son obligatorios."
    echo "-------------------------------------------------------------------------------------------------------------"
    echo "Factor de escala para el tamaño de la marca de agua -s [factor_escala]"
    echo "Por ejemplo: -s 0.15 , un factor de escala del 15% es adecuado para la fotografia de paisajes."
    echo "-------------------------------------------------------------------------------------------------------------"
    
    
    exit 1
fi

# Verificación de la existencia de la ruta de la marca de agua
if [ ! -f "$MARCA_DE_AGUA" ]; then
    echo "La ruta de la marca de agua ($MARCA_DE_AGUA) no existe."
    exit 1
fi

# Verificación de la existencia del directorio de imágenes
if [ ! -d "$DIRECTORIO_IMAGENES" ]; then
    echo "El directorio de imágenes ($DIRECTORIO_IMAGENES) no existe."
    exit 1
fi

# Verificación de la existencia del directorio de salida
if [ ! -d "$DIRECTORIO_SALIDA" ]; then
    echo "El directorio de salida ($DIRECTORIO_SALIDA) no existe. Creando el directorio..."
    mkdir -p "$DIRECTORIO_SALIDA"
fi

contador=0
tiempo_inicio=$(date +%s)


# Aplicar marca de agua a cada imagen en el directorio
for IMAGEN in "$DIRECTORIO_IMAGENES"/*; do
    if [ -f "$IMAGEN" ] && file --mime-type "$IMAGEN" | grep -q -E "image/(png|gif|jpeg|jpg)"; then
        nombre_imagen=$(basename "$IMAGEN")
        
        # La expresión ${nombre_imagen##*.} utiliza un mecanismo de expansión de parámetros en el shell 
        # de Unix para extraer la extensión de un nombre de archivo.
        # Significa eliminar todo hasta el último punto en el nombre del archivo, y devolver lo que queda.
        
        extension_imagen="${nombre_imagen##*.}"
        
        echo "Aplicando marca de agua a $DIRECTORIO_IMAGENES$nombre_imagen -> $DIRECTORIO_SALIDA${nombre_imagen%.*}_wm.$extension_imagen"
        #echo "Aplicando marca de agua a $DIRECTORIO_IMAGENES/$nombre_imagen -> $DIRECTORIO_SALIDA/${nombre_imagen%.*}_wm.$extension_imagen"
        
        # Obtener el tamaño de la imagen (ancho x altura)
        tamano_imagen=$(identify -format "%wx%h" "$IMAGEN")
        
        # Separar el ancho y la altura
        ancho_imagen=$(echo "$tamano_imagen" | cut -d'x' -f 1)
        altura_imagen=$(echo "$tamano_imagen" | cut -d'x' -f 2)
        
        # Calcular el tamaño de la marca de agua proporcional al tamaño de la imagen
        tamano_marca=$(echo "$ancho_imagen * $FACTOR_ESCALA" | bc)
        
        # Redimensionar la marca de agua al tamaño calculado y eliminar el perfil de color
        marca_de_agua_redimensionada=$(mktemp)
        convert "$MARCA_DE_AGUA" -resize "${tamano_marca}x${tamano_marca}" -strip "$marca_de_agua_redimensionada"
        
        # Aplicar marca de agua al pie de la imagen con margen inferior centrado
        composite -dissolve 50% -gravity South -geometry +0+3 "$marca_de_agua_redimensionada" "$IMAGEN" "$DIRECTORIO_SALIDA/${nombre_imagen%.*}_wm.$extension_imagen"
        
        # Eliminar el archivo temporal de la marca de agua redimensionada
        rm "$marca_de_agua_redimensionada"
        
        # Incrementar el contador por cada imagen procesada
		contador=$((contador + 1))
    fi
done

# Calcular el tiempo total transcurrido
tiempo_fin=$(date +%s)
tiempo_total=$((tiempo_fin - tiempo_inicio))

# Convertir tiempo total a formato hh:mm:ss
horas=$((tiempo_total / 3600))
minutos=$(( (tiempo_total % 3600) / 60 ))
segundos=$((tiempo_total % 60))

# Mostrar el total de imágenes procesadas y el tiempo que tomó
echo "-------------------------------------------------------------------------------------------------------------"
echo "Total de imágenes procesadas: $contador"
# Formatear la salida
printf "Tiempo total transcurrido: %02d:%02d:%02d\n" $horas $minutos $segundos




Para utilizar el script en Debian, necesitas tener instalados los siguientes paquetes:

ImageMagick: Este paquete proporciona las herramientas identify, convert, y composite, que se utilizan en el script para manipular imágenes y aplicar la marca de agua.
Para instalar estos paquetes en Debian, puedes usar el siguiente comando:
 
sudo apt-get update
sudo apt-get install imagemagick bc