Créer une Animation ASCII Personnalisée dans le Terminal avec Python et Bash

L'affichage de séquences animées directement dans un terminal est une technique visuelle intrigante, souvent utilisée pour des économiseurs d'écran ou des effets de style. Cet article explique comment concevoir une commande shell personnalisée pour générer une animation à base de caractères ASCII à partir d'une série d'images, en combinant Python et un script Bash.

Le processus se décompose en deux étapes principales :

  1. Développer un script Python capible de convertir une image en sa représentation textuelle ASCII.
  2. Mettre en place un script Bash pour orchestrer l'affichage séquentiel de ces représentations ASCII, créant ainsi une animation.

1. Conversion d'Image en ASCII avec Python

Nous utiliserons la bibliothèque PIL (Pillow) pour le traitement d'images et argparse pour la gestion des paramètres d'entrée.

Dépendances :

from PIL import Image
import argparse

Configuraton des Arguments :

Le script acceptera le chemin de l'image source, ainsi qu'une largeur et une hauteur optionnelles pour la sortie ASCII. Ces dimensions déterminent la résolution de l'art ASCII généré.

parser_config = argparse.ArgumentParser(description="Convertit une image en art ASCII pour affichage terminal.")
parser_config.add_argument('source_image_path', help="Chemin du fichier image à convertir.")
parser_config.add_argument('--output_width', type=int, default=120, help="Largeur souhaitée pour l'art ASCII.")
parser_config.add_argument('--output_height', type=int, default=36, help="Hauteur souhaitée pour l'art ASCII.")
arguments = parser_config.parse_args()

fichier_image_entree = arguments.source_image_path
largeur_sortie = arguments.output_width
hauteur_sortie = arguments.output_height

Jeu de Caractères ASCII :

Cette liste de caractères est ordonnée du plus dense (sombre) au moins dense (clair/transparent). Un pixel sombre sera remplacé par un caractère au début de la liste, tandis qu'un pixel clair le sera par un caractère plus loin dans la liste (ou un espace).

caracteres_densite = list("@#B%8&WM*oahkbdpqwmZO0QLCJUYXzcvunxrjft/\\|()1{}[]?-_+~<>i!lI;:,\"^`'. ")

Fonction de Conversion RVB en Caractère :

Cette fonction prend les composantes RVB (et une valeur alpha pour la transparence) d'un pixel et retourne le caractère ASCII correspondant. Elle calcule la valeur de gris du pixel, puis l'utilise pour indexer le jeu de caractères.

def obtenir_caractere_ascii(rouge, vert, bleu, alpha_canal=255):
    """
    Convertit les valeurs RVB d'un pixel en un caractère ASCII basé sur sa luminosité.
    """
    if alpha_canal == 0:  # Pixel entièrement transparent
        return ' '
    
    # Calcul de la valeur de gris (formule de luminosité perceptuelle)
    valeur_gris = int(0.2126 * rouge + 0.7152 * vert + 0.0722 * bleu)
    
    # Mapper la valeur de gris à un caractère dans notre liste
    # La plage de gris est de 0 à 255.
    # On divise cette plage par le nombre de caractères pour obtenir une "unité" par caractère.
    index_caractere = int(valeur_gris / (256.0 / len(caracteres_densite)))
    
    # S'assurer que l'index reste dans les limites de la liste
    index_caractere = min(index_caractere, len(caracteres_densite) - 1)
    
    return caracteres_densite[index_caractere]

Logique Principale du Script Python :

Le script ouvre l'image, la redimensionne aux dimensions spécifiées, puis itère sur chaque pixel pour le convertir en un caractère ASCII. L'ensemble des caractères forme une chaîne qui est ensuite imprimée sur la sortie standard.

def generer_ascii_art():
    try:
        image_source = Image.open(fichier_image_entree)
    except FileNotFoundError:
        print(f"Erreur : L'image '{fichier_image_entree}' n'a pas été trouvée.", file=sys.stderr)
        sys.exit(1)
    except Exception as e:
        print(f"Erreur lors de l'ouverture de l'image : {e}", file=sys.stderr)
        sys.exit(1)

    image_redimensionnee = image_source.resize((largeur_sortie, hauteur_sortie), Image.NEAREST)

    representation_ascii = []
    for y in range(hauteur_sortie):
        ligne_chars = []
        for x in range(largeur_sortie):
            pixel_data = image_redimensionnee.getpixel((x, y))
            
            # Gérer les différents formats de pixels (RVB, RVBA, Niveaux de gris)
            if isinstance(pixel_data, tuple):
                if len(pixel_data) == 4: # RGBA
                    r, g, b, a = pixel_data
                else: # RGB
                    r, g, b = pixel_data
                    a = 255 # Supposons opaque
            else: # Grayscale
                r = g = b = pixel_data
                a = 255

            ligne_chars.append(obtenir_caractere_ascii(r, g, b, a))
        representation_ascii.append("".join(ligne_chars))
    
    print("\n".join(representation_ascii))

import sys # Ajouter sys pour gérer les sorties d'erreur

if __name__ == '__main__':
    generer_ascii_art()

2. Création de l'Animation avec un Script Bash

Maintenant que nous avons un script Python capable de générer une "image" ASCII, nous allons utiliser un script Bash pour les afficher séquentiellement. Le script Bash effacera l'écran, appellera le script Python pour une image, puis fera une courte pause avant de passer à l'image suivante, créant ainsi l'illusion d'une animation.

Le Script d'Animation (animation_ascii.sh) :

Créez un fichier exécutable, par exemple animation_ascii.sh, avec le contenu suivant :

#!/bin/bash

# Chemin vers votre script Python
PYTHON_SCRIPT_PATH="/chemin/vers/votre_script_ascii.py" # Mettez le chemin réel

# Liste des images à utiliser pour l'animation
# Assurez-vous que ces chemins sont corrects
DECLARE -a IMAGE_FILES=(
    "~/Images/frame_a.jpg"
    "~/Images/frame_b.png"
    "~/Images/frame_c.jpeg"
    "~/Images/frame_d.jpg"
)

# Paramètres de sortie pour l'art ASCII
TARGET_WIDTH=100
TARGET_HEIGHT=30

# Délai entre chaque frame (en secondes)
FRAME_DELAY=0.1

# Boucle infinie pour l'animation
while true; do
    for current_image in "${IMAGE_FILES[@]}"; do
        clear # Efface le contenu du terminal
        # Exécute le script Python pour convertir et afficher l'image actuelle
        python3 "$PYTHON_SCRIPT_PATH" "$current_image" --output_width "$TARGET_WIDTH" --output_height "$TARGET_HEIGHT"
        sleep "$FRAME_DELAY" # Pause avant la prochaine image
    done
done

N'oubliez pas de remplacer /chemin/vers/votre_script_ascii.py par le chemin réel de votre script Python et de fournir les chemins corrects pour vos fichiers d'images.

Rendre le Script Exécutable :

chmod +x /chemin/vers/animation_ascii.sh

Configuration d'un Alias Shell :

Pour lancer facielment votre animation, vous pouvez ajouter un alias à votre fichier de configuration shell (par exemple, ~/.bashrc ou ~/.zshrc).

alias artanim='bash /chemin/vers/animation_ascii.sh'

Après avoir enregistré les modifications, rechargez votre configuration shell (par exemple, avec source ~/.bashrc ou en rouvrant votre terminal). Vous pouvez maintenant lancer votre animation personnalisée en tapant simplement artanim.

Étiquettes: Python PIL bash ASCII Art terminal

Publié le 10 juillet à 16h23