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)