
Vous pouvez créer des vignettes carrées ou circulaires à l’aide de la bibliothèque de traitement d’image de Python Pillow (PIL).
Bien qu’il existe une méthode appelée thumbnail() dans le module Image de Pillow, elle redimensionne simplement l’image pour l’adapter à la taille spécifiée.
Cet article décrit le contenu suivant.
- Comment faire un carré d’image rectangulaire
- Recadrer un carré à partir d’une image rectangulaire
- Ajouter un rembourrage pour faire un rectangle carré
- Rogner une image carrée en cercle
- Faire de l’arrière-plan une couleur unie
- Rendre le fond transparent
- Exemple de code pour le traitement par lots
Consultez les articles suivants pour l’installation et l’utilisation de base de Pillow (PIL).
Importez Image, ImageDraw et ImageFilter à partir de PIL. ImageDraw et ImageFilter sont utilisés pour dessiner et traiter des cercles. Lors de la création d’une image miniature carrée, elles peuvent être omises.
Pour le traitement par lots, importez os et glob.
Lisez l’image utilisée dans les exemples suivants, et décidez de la largeur (= hauteur) de l’image miniature que vous souhaitez obtenir finalement.
import os
import glob
from PIL import Image, ImageDraw, ImageFilter
im = Image.open('data/src/astronaut_rect.bmp')
thumb_width = 200
Comment faire un carré d’image rectangulaire
Étant donné que le redimensionnement d’une image rectangulaire en carré avec resize() du module Image modifie le rapport d’aspect, utilisez l’une des méthodes suivantes.
- Recadrer un carré à partir d’une image rectangulaire
- Ajouter un rembourrage pour faire un rectangle carré
Recadrer un carré à partir d’une image rectangulaire
Rogner une zone d’une image avec crop().
Définissez une fonction pour recadrer la zone centrale de l’image.
def crop_center(pil_img, crop_width, crop_height):
img_width, img_height = pil_img.size
return pil_img.crop(((img_width - crop_width) // 2,
(img_height - crop_height) // 2,
(img_width + crop_width) // 2,
(img_height + crop_height) // 2))
Exemple d’utilisation :
im_thumb = crop_center(im, thumb_width, thumb_width)
im_thumb.save('data/dst/astronaut_thumbnail_center_square.jpg', quality=95)
Au lieu de recadrer la zone de la taille de la vignette, vous pouvez recadrer le carré de plus grande taille (= carré rectangulaire à côté court) puis le redimensionner.
Définissez une fonction pour recadrer le carré le plus grand. Il utilise une fonction pour recadrer la zone centrale de l’image.
def crop_max_square(pil_img):
return crop_center(pil_img, min(pil_img.size), min(pil_img.size))
Exemple d’utilisation :
Après avoir transformé l’image rectangulaire en carré, elle est redimensionnée par resize() à la taille de l’image miniature souhaitée.
im_thumb = crop_max_square(im).resize((thumb_width, thumb_width), Image.LANCZOS)
im_thumb.save('data/dst/astronaut_thumbnail_max_square.jpg', quality=95)
Ajouter un rembourrage pour faire un rectangle carré
Si vous souhaitez conserver l’intégralité de l’image rectangulaire d’origine, ajoutez un rembourrage en haut, en bas, à gauche ou à droite pour la rendre carrée.
new() peut être utilisé pour générer une image solide et la coller avec paste().
Définissez une fonction qui ajoute un rembourrage pour éventuellement devenir un carré de la taille du côté long du rectangle.
def expand2square(pil_img, background_color):
width, height = pil_img.size
if width == height:
return pil_img
elif width > height:
result = Image.new(pil_img.mode, (width, width), background_color)
result.paste(pil_img, (0, (width - height) // 2))
return result
else:
result = Image.new(pil_img.mode, (height, height), background_color)
result.paste(pil_img, ((height - width) // 2, 0))
return result
Exemple d’utilisation :
Après avoir transformé l’image rectangulaire en carré, elle est réduite par resize() à la taille de l’image miniature souhaitée.
im_thumb = expand2square(im, (0, 0, 0)).resize((thumb_width, thumb_width), Image.LANCZOS)
im_thumb.save('data/dst/astronaut_thumbnail_expand.jpg', quality=95)
Rogner une image carrée en cercle
Si vous souhaitez générer une image miniature circulaire, vous devez recadrer une image carrée en cercle.
Il existe deux façons :
- donner à l’arrière-plan une couleur unie (blanc, noir, etc.)
- rendre le fond transparent (= rendre le png transparent)
Faire de l’arrière-plan une couleur unie
Utilisez composite() pour composer deux images en fonction de l’image du masque.
Dessinez un cercle et utilisez-le comme image de masque. Pour plus de détails sur le dessin, consultez l’article suivant.
Créez une image unicolore de la couleur d’arrière-plan souhaitée avec new() et composez-la avec l’image carrée avec un masque circulaire.
La bordure est lissée en brouillant l’image du masque avec ImageFilter. Étant donné que la zone du cercle s’étend lorsqu’elle est floue, il est nécessaire de dessiner d’abord un cercle plus petit.
Définissez la fonction suivante. Spécifiez la couleur d’arrière-plan background_color, la taille du flou blur_radius et le décalage de décalage. Pas de flou avec blur_radius=0.
def mask_circle_solid(pil_img, background_color, blur_radius, offset=0):
background = Image.new(pil_img.mode, pil_img.size, background_color)
offset = blur_radius * 2 + offset
mask = Image.new("L", pil_img.size, 0)
draw = ImageDraw.Draw(mask)
draw.ellipse((offset, offset, pil_img.size[0] - offset, pil_img.size[1] - offset), fill=255)
mask = mask.filter(ImageFilter.GaussianBlur(blur_radius))
return Image.composite(pil_img, background, mask)
Exemple d’utilisation :
im_square = crop_max_square(im).resize((thumb_width, thumb_width), Image.LANCZOS)
im_thumb = mask_circle_solid(im_square, (0, 0, 0), 4)
im_thumb.save('data/dst/astronaut_thumbnail_mask_circle_solid.jpg', quality=95)
Rendre le fond transparent
Utilisez putalpha(), qui ajoute un canal alpha à l’image.
Le flux est le même que lors de l’utilisation d’un fond uni d’une seule couleur.
def mask_circle_transparent(pil_img, blur_radius, offset=0):
offset = blur_radius * 2 + offset
mask = Image.new("L", pil_img.size, 0)
draw = ImageDraw.Draw(mask)
draw.ellipse((offset, offset, pil_img.size[0] - offset, pil_img.size[1] - offset), fill=255)
mask = mask.filter(ImageFilter.GaussianBlur(blur_radius))
result = pil_img.copy()
result.putalpha(mask)
return result
Les images transparentes sont enregistrées au format png.
im_square = crop_max_square(im).resize((thumb_width, thumb_width), Image.LANCZOS)
im_thumb = mask_circle_transparent(im_square, 4)
im_thumb.save('data/dst/astronaut_thumbnail_mask_circle_transparent.png')
Exemple de code pour le traitement par lots
Créez des images miniatures collectivement à partir de fichiers image dans n’importe quel répertoire (dossier).
Cela peut être fait de la même manière que le redimensionnement par lots.
Générez des images miniatures des fichiers image dans src_dir et enregistrez-les dans dst_dir.
src_dir = 'data/temp/src'
dst_dir = 'data/temp/dst'
files = glob.glob(os.path.join(src_dir, '*.jpg'))
for f in files:
im = Image.open(f)
im_thumb = crop_max_square(im).resize((thumb_width, thumb_width), Image.LANCZOS)
ftitle, fext = os.path.splitext(os.path.basename(f))
im_thumb.save(os.path.join(dst_dir, ftitle + '_thumbnail' + fext), quality=95)