Avant tout, qu’est-ce qu’une galerie de miniatures en Python ? C’est une image qui va réunir toutes les images d’un répertoire (par exemple). Mais comment créer facilement ce genre d’images à l’aide de Python ? Je vous explique cela…
Galerie de miniatures en Python: les contraintes
Pour simplifier les choses, nous allons partir du principe que toutes les images ont les mêmes dimensions. Ce sera bien plus simple.
Nous allons implémenter une fonction Python “miniatures” qui va admettre quelques paramètres:
- columns : le nombre de colonnes souhaitée dans la galerie
- width : la largeur totale de l’image souhaitée
- esp : l’espace entre chaque miniature
- rep : le répertoire où se trouvent les images
- ext : une liste où seront placées les extensions autorisées des images
Galerie de miniatures en Python: un peu de maths maintenant…
Calcul des dimensions des miniatures
L’espace totale réservée pour les miniatures est égale à :
width – columns*esp
Il suffira donc de diviser cette espace par columns pour obtenir la largeur \(\ell^\prime\) de chaque miniature. La hauteur se calcule par suite à l’aide du coefficient de réduction:$$ \text{hauteur}=h’=\frac{\ell^\prime}{\ell}\times h$$où \(\ell\) désigne la largeur de l’image originale et \(h\) sa hauteur.
Hauteur de la galerie
Je vais noter N le nombre d’images dans le répertoire.
Je vais insérer une espace de esp/2 en haut et en bas, et une espace de esp entre chaque miniature. Le nombre de lignes de la galerie sera égal:
- au quotient de la division euclidienne de N par columns si le reste de cette division est nul;
- au quotient de la division euclidienne de N par columns, augmenté de 1, si le reste de cette division est non nul;
Je vais noter \(n\) le nombre de lignes ainsi obtenu.
Ainsi, la hauteur de la galerie sera égale à:$$(h^\prime + esp)\times n.$$
J’ai désormais tous les nombres nécessaires pour construire ma galerie.
Galerie de miniatures en Python: implémentation
Nous allons faire appel au module PIL de Python pour construire notre galerie. La logique sera la suivante:
- parcourir le répertoire
- pour chaque fichier, créer une miniature à l’aide de la fonction thumbnail de PIL
- insérer la miniature au bon endroit dans la galerie
- supprimer la miniature
from PIL import Image, ExifTags from os import listdir,remove from os.path import isfile def miniatures(rep = '.' , columns = None , width = 800, esp = 5, extensions = ['jpg','jpeg','bmp','png']): """ width = largeur de l'image contenant les miniatures (en px) esp = espaces entre les miniatures (en px) """ # on liste toutes les images img = dict() largeur, hauteur = 0,0 for f in listdir( rep ): if f[-3:] in extensions: i = Image.open(rep + '/' + f) img[ f ] = i.size if largeur == 0: largeur, hauteur = i.width, i.height # on crée les miniatures largeur_miniatures = (width - columns*esp) // columns hauteur_miniatures = int( (largeur_miniatures/largeur) * hauteur ) if len(img)%columns == 0: lines = len( img ) // columns else: lines = len( img ) // columns + 1 hauteur_totale = lines * (hauteur_miniatures + esp) miniatures = Image.new('RGBA', ( width , hauteur_totale )) n = 1 MAX_SIZE = (largeur_miniatures, hauteur_miniatures) for f in listdir( rep ): if f[-3:] in extensions: if n == 1: x,y = esp//2,esp//2 elif n%columns == 1: y += hauteur_miniatures + esp x = esp//2 else: x += esp + largeur_miniatures print(rep + '/' + f) i = Image.open(rep + '/' + f) i.thumbnail(MAX_SIZE) print('Sauvegarde de la miniature.') i.save(rep + '/mini_' + f) i_mini = Image.open(rep + '/mini_' + f).convert("RGBA") miniatures.alpha_composite(i_mini, dest=(x,y)) print(f'Mise de la miniature en {(x,y)}.') n += 1 remove(rep + '/mini_' + f) print('Suppression de la miniature.') miniatures = miniatures.convert("RGB") miniatures.save( 'miniatures.jpg' ) miniatures.show()
Voici un exemple sur les derniers fonds d’écran que j’ai fait (voir galerie):
>>> miniatures(columns = 3)
>>> miniatures(columns = 5)