Dessin de texte chinois illisible avec Pillow
L'ajout de texte à une image est un besoin courant en traitement d'image, comme l'ajout de filigranes aux images, la création d'affiches, etc. Pillow fournitImageDrawmodule pour implémenter cette fonctionnalité.
Étapes de base
Les étapes de base pour ajouter du texte à une image sont les suivantes :
- Ouvrir ou créer une image
- Créer un objet ImageDraw
- Spécifier la police
- Utiliser
text()méthode pour ajouter du texte - Enregistrer l'image
Exemple
Exemple
# 1. Créer une nouvelle image
image = Image.new('RGB', (400, 200), color=(255, 255, 255))
# 2. Créer un objet ImageDraw
draw = ImageDraw.Draw(image)
# 3. Spécifier la police (en utilisant la police par défaut ici)
# Remarque : la police par défaut peut ne pas prendre en charge le chinois
font = ImageFont.load_default()
# 4. Ajouter du texte
draw.text((10, 10), "Hello, Pillow!", fill="black", font=font)
# 5. Enregistrer l'image
image.save('output.png')
Ajout de polices chinoises
Par défaut, la police par défaut de Pillow ne prend pas en charge les caractères chinois.
Pour ajouter du chinois à une image, nous devons utiliser un fichier de police qui prend en charge le chinois (généralement au format .ttf ou .otf).
Obtention de polices chinoises
Vous pouvez obtenir des polices chinoises à partir des sources suivantes :
Utilisez les polices chinoises fournies avec le système (comme simsun.ttc de Windows)
Téléchargez depuis des sites de polices gratuites (comme Source Han Sans, Alibaba PuHuiTi, etc.).
Achetez des polices commerciales (faites attention aux problèmes de droits d'auteur)
Téléchargements de bibliothèques de polices chinoises open source :https://github.com/wordshub/free-font。

Exemple de code pour utiliser des polices chinoises
Exemple
# 1. Créer une nouvelle image
image = Image.new('RGB', (400, 200), color=(255, 255, 255))
# 2. Créer un objet ImageDraw
draw = ImageDraw.Draw(image)
# 3. Spécifier une police chinoise
# Remarque : Remplacez-le par le chemin d'un fichier de police qui existe sur votre système
font_path = "SimHei.ttf" # Chemin de la police SimHei
font_size = 20
font = ImageFont.truetype(font_path, font_size)
# 4. Ajouter du texte chinois
draw.text((10, 10), "Hello, Pillow!", fill="red", font=font)
# 5. Enregistrer l'image
image.save('chinese_output.png')
La sortie est la suivante, le chinois s'affiche correctement :

Techniques avancées de mise en page de texte
Contrôle de la position du texte
text()Le premier paramètre de la méthode est la coordonnée (x, y), qui indique la position en haut à gauche du texte. Nous pouvons contrôler la position du texte par calcul.
Exemple
# 1. Créer une nouvelle image
image = Image.new('RGB', (400, 200), color=(255, 255, 255))
# 2. Créer un objet ImageDraw
draw = ImageDraw.Draw(image)
# 3. Spécifier une police chinoise
# Remarque : Remplacez-le par le chemin d'un fichier de police qui existe sur votre système
font_path = "SimHei.ttf" # Chemin de la police SimHei
font_size = 20
font = ImageFont.truetype(font_path, font_size)
# 4. Ajouter du texte chinois
# Centrer le texte
text = "Texte centré"
bbox = draw.textbbox((0, 0), text, font=font)
text_width = bbox[2] - bbox[0]
text_height = bbox[3] - bbox[1]
image_width, image_height = image.size
x = (image_width - text_width) / 2
y = (image_height - text_height) / 2
draw.text((x, y), text, fill="red", font=font)
# 5. Enregistrer l'image
image.save('chinese_output.png')
Le résultat est le suivant, le texte est centré :

Traitement de texte multiligne
Pillow ne prend pas directement en charge le retour à la ligne automatique, mais nous pouvons l'implémenter manuellement :
Exemple
# 1. Créer une nouvelle image
image = Image.new('RGB', (400, 200), color=(255, 255, 255))
# 2. Créer un objet ImageDraw
draw = ImageDraw.Draw(image)
# 3. Spécifier une police chinoise
# Remarque : Remplacez-le par le chemin d'un fichier de police qui existe sur votre système
font_path = "SimHei.ttf" # Chemin de la police SimHei
font_size = 20
font = ImageFont.truetype(font_path, font_size)
# 4. Ajouter du texte chinois
# Affichage multiligne
# Le texte chinois à afficher
text = Il s'agit d'un texte relativement long, et nous devons le diviser en plusieurs lignes pour une meilleure lisibilité.
max_width = 200 # Largeur maximale par ligne (pixels)
lines = [] # Stocker le texte après le retour à la ligne
current_line = "" # La ligne actuelle en cours de traitement
# Parcourir le texte caractère par caractère pour déterminer si un retour à la ligne est nécessaire
for char in text:
test_line = current_line + char
# Calculer la largeur de la ligne actuelle pour déterminer si elle dépasse la largeur maximale
if draw.textbbox((0, 0), test_line, font=font)[2] <= max_width:
current_line = test_line
else:
lines.append(current_line) # La ligne actuelle est pleine, l'ajouter au résultat
current_line = char # Une nouvelle ligne commence par le caractère actuel
if current_line:
lines.append(current_line) # Ajouter la dernière ligne
y_text = 10 # Coordonnée y initiale
# Dessiner le texte ligne par ligne
for line in lines:
draw.text((10, y_text), line, fill="red", font=font)
bbox = draw.textbbox((0, 0), line, font=font)
line_height = bbox[3] - bbox[1] # Calculer la hauteur de la ligne actuelle
y_text += line_height # Mettre à jour la coordonnée y pour préparer le dessin de la ligne suivante
# 5. Enregistrer l'image
image.save('chinese_output.png')
La sortie est la suivante :

Paramètres de style de texte
Nous pouvons définir les styles de texte à l'aide de fichiers de police ou des fonctionnalités de Pillow :
Exemple
# 1. Créer une nouvelle image
image = Image.new('RGB', (400, 200), color=(255, 255, 255))
# 2. Créer un objet ImageDraw
draw = ImageDraw.Draw(image)
# 3. Spécifier une police chinoise
# Remarque : Remplacez-le par le chemin d'un fichier de police qui existe sur votre système
font_path = "SimHei.ttf" # Chemin de la police SimHei
font_size = 20
font = ImageFont.truetype(font_path, font_size)
# 4. Ajouter du texte chinois
# Définir la couleur du texte
draw.text((10, 10), "Colored text", fill=(255, 0, 0), font=font) # Rouge
# Ajouter un contour de texte (implémenté en dessinant plusieurs fois)
text = "Texte avec contour"
position = (50, 50)
# Dessiner d'abord un fond noir (contour)
for x_offset in [-1, 0, 1]:
for y_offset in [-1, 0, 1]:
if x_offset != 0 or y_offset != 0:
draw.text((position[0]+x_offset, position[1]+y_offset), text, fill="black", font=font)
# Dessiner ensuite le premier plan en blanc
draw.text(position, text, fill="white", font=font)
# 5. Enregistrer l'image
image.save('chinese_output.png')
La sortie est la suivante :

Exemples d'applications pratiques
Ajout d'un filigrane à une image
Exemple
# 1. Créer une nouvelle image
# Ouvrir l'image originale
original_image = Image.open("tiger.jpeg")
# Créer un calque transparent pour le filigrane
watermark = Image.new("RGBA", original_image.size, (0, 0, 0, 0))
draw = ImageDraw.Draw(watermark)
# Définir la police du filigrane
font_path = "SimHei.ttf" # Chemin de la police SimHei
font_size = 60
font = ImageFont.truetype(font_path, font_size)
# Ajouter le texte du filigrane
text = WWW.example.com Ajouter un test de filigrane
bbox = draw.textbbox((0, 0), text, font=font)
text_width = bbox[2] - bbox[0]
text_height = bbox[3] - bbox[1]
x = original_image.width - text_width - 20
y = original_image.height - text_height - 20
draw.text((x, y), text, fill=(255, 0, 0, 128), font=font) # Rouge semi-transparent
# Fusionner le filigrane et l'image originale
watermarked_image = Image.alpha_composite(
original_image.convert("RGBA"),
watermark
)
# Enregistrer le résultat
watermarked_image.save("watermarked_photo.png")
L'effet est le suivant :
Création d'une affiche
Exemple
# Créer l'arrière-plan de l'affiche
poster = Image.new("RGB", (800, 1200), (30, 30, 60))
draw = ImageDraw.Draw(poster)
# Définir la police du titre
title_font = ImageFont.truetype("SimHei.ttf", 60)
# Définir la police du corps de texte
body_font = ImageFont.truetype("SimHei.ttf", 30)
# Ajouter le titre
title = Cours sur le traitement d'images avec Python
draw.text((50, 50), title, fill=(255, 255, 255), font=title_font)
# Ajouter le corps du texte
content = """Date : 15 avril 2025
Lieu : Salle de réunion en ligne
Présentateur : WWW.example.com
Contenu : Utiliser la bibliothèque Python Pillow pour le traitement d'images"""
y_position = 150
for line in content.split("\n"):
draw.text((50, y_position), line, fill=(220, 220, 220), font=body_font)
y_position += 40
# Enregistrer l'affiche
poster.save("event_poster.png")
L'effet est le suivant :
Grâce aux méthodes et exemples ci-dessus, vous devriez pouvoir ajouter facilement des polices chinoises dans Pillow. N'oubliez pas de prendre en compte les problèmes de droits d'auteur des polices dans les applications pratiques, et d'ajuster les styles et positions du texte selon vos besoins.
Autres extensions