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)

