Images SVG WeasyPrint : rétablir les logos des PDF
Corrige les logos SVG absents des PDF WeasyPrint avec une URL de base et des dimensions CSS explicites, puis vérifie tracés, proportions et dessin dans le PDF.
Sur cette page
WeasyPrint peut placer un SVG dans un PDF au moyen d’un élément image HTML. Si le logo disparaît lorsque tu fournis le HTML sous forme de chaîne, vérifie d’abord l’URL de l’image : un chemin relatif a besoin d’une URL de base. Une fois le fichier chargé, règle sa taille imprimée en CSS et inspecte le PDF enregistré. La référence actuelle de l’API WeasyPrint documente cette exigence concernant base_url.
L’exemple ci-dessous reproduit ce cas d’image absente avec un logo original en forme de cadre. Il vérifie aussi que le PDF corrigé contient de la géométrie vectorielle à la taille demandée. Si tu possèdes déjà un SVG, pars de ce fichier. La vectorisation n’intervient dans cette méthode que lorsque le dessin source existe sous forme de pixels.
Vérifie le chargement avant de modifier le dessin
Un PDF peut être créé même si son logo est absent. Vérifie l’avertissement concernant la ressource, résous le chemin de l’image et relance le rendu avec le même SVG avant de modifier ses formes ou de le convertir dans un autre format.
Reproduis le SVG absent avec un petit document
Nous avons testé avec Python 3.13.9 et WeasyPrint 70.0. Utilise un environnement de projet et installe cette version précise :
python -m pip install "weasyprint==70.0"
python -m weasyprint --infoWeasyPrint nécessite aussi des bibliothèques natives, dont Pango. Suis ses instructions d’installation selon le système d’exploitation si l’import ou la commande de version échoue. Une bibliothèque native manquante est un problème différent d’un logo manquant.
Crée cette structure de dossiers :
example/
render.py
assets/
logo.svgEnregistre ce dessin de démonstration original sous assets/logo.svg. L’ouverture centrale donne un élément plus utile à inspecter qu’un simple rectangle plein. Il s’agit de géométrie écrite à la main, et non d’une conversion PerfectVector.
<svg xmlns="http://www.w3.org/2000/svg"
width="120" height="60" viewBox="0 0 120 60">
<path fill="#087f8c" fill-rule="evenodd"
d="M0 0H120V60H0Z M20 15V45H100V15Z"/>
</svg>Place le code suivant dans render.py :
from pathlib import Path
import logging
from weasyprint import HTML
logging.basicConfig(level=logging.WARNING)
root = Path(__file__).resolve().parent
html = """<!doctype html>
<html>
<head>
<meta charset="utf-8">
<style>
@page { size: A4; margin: 20mm; }
body { margin: 0; }
.logo { display: block; width: 60mm; height: auto; }
</style>
</head>
<body>
<img class="logo" src="assets/logo.svg" alt="Frame logo">
</body>
</html>
"""
HTML(string=html).write_pdf(root / "missing-base.pdf")
HTML(
string=html,
base_url=root.as_uri() + "/",
).write_pdf(root / "resolved.pdf")Exécute python render.py. Dans notre premier PDF, le cadre était absent et le texte alternatif de l’image apparaissait. Le journal contenait :
Relative URI reference without a base URI: assets/logo.svgLe second PDF affichait le cadre bleu-vert avec son ouverture intacte. Les deux appels ont produit un fichier : la seule existence d’un PDF n’était donc pas un critère de réussite utile.
Donne aux chemins relatifs un dossier de départ stable
assets/logo.svg identifie un fichier par rapport à un autre emplacement. Le base_url du second appel fournit cet emplacement de départ. root.as_uri() crée une URI de fichier absolue ; la barre oblique finale en fait une base de répertoire. Le logo reste dans le même dossier assets et le contenu SVG ne change pas.
L’utilisation de Path(__file__) rattache aussi l’exemple au dossier du script lorsque tu le lances depuis un autre répertoire de travail. Dans un notebook, utilise plutôt un dossier de projet explicite, puisque __file__ n’est normalement pas disponible.

Un autre test de contrôle est utile. Enregistre le HTML sous invoice.html à côté de render.py et charge le fichier lui-même :
HTML(filename=str(root / "invoice.html")).write_pdf(
root / "from-file.pdf"
)WeasyPrint peut déduire une base du nom de fichier ou de l’URL d’entrée. Notre test à partir d’un fichier a produit le même cadre que le cas avec base explicite. Une chaîne HTML n’a pas de nom de fichier correspondant permettant cette déduction. Ces modes d’entrée et leurs règles de résolution de base sont documentés dans le constructeur HTML.
Pour une image protégée par une connexion, une URL correcte peut rester insuffisante. La documentation des récupérateurs d’URL indique que le client HTTP par défaut ne fournit ni cookies ni authentification. Utilise le mécanisme de récupération de ressources approuvé pour ton application et teste-le dans l’environnement qui génère le PDF. Ne suppose pas qu’un logo visible dans ton navigateur connecté est accessible au processus PDF.
Règle la taille de l’image séparément de celle de la page PDF
L’exemple utilise @page pour la feuille A4 et les marges, tandis que .logo donne à l’image une largeur de 60 mm. Son rapport source 2:1 lui donne une hauteur de 30 mm avec height: auto. Dans notre PDF enregistré, le cadre mesurait 60 × 30 mm et commençait à 20 mm des bords supérieur et gauche de la page.
Ici, le dessin remplit entièrement son viewBox. Ton logo peut contenir de l’espace vide dans ce rectangle : une boîte d’image de 60 mm peut alors contenir un symbole visiblement plus étroit. Vérifie le canevas SVG avant de compenser par une largeur CSS arbitrairement plus grande. Le guide de la taille d’importation SVG explique cette distinction plus en détail.
Conserve la valeur par défaut zoom=1 de write_pdf() lorsque tu vérifies les dimensions physiques. La référence de sortie PDF de WeasyPrint avertit qu’un changement de zoom redimensionne aussi les unités CSS physiques et les formats de page nommés.
| Ce que tu observes | Première vérification | Étape suivante |
|---|---|---|
| Le texte alternatif remplace le logo | URL de l’image et journal des ressources | Fournis une URL de base valide ou une URL absolue accessible |
| Le logo apparaît à la mauvaise taille | Largeur CSS et rapport de la source | Définis une largeur physique et inspecte le canevas SVG |
| Une partie du dessin manque | Limites de la source et fonctionnalité SVG concernée | Réduis le cas à un petit exemple défaillant et compare le PDF exporté |
| Le rendu local fonctionne, le rendu serveur échoue | Fichiers, polices et accès aux URL disponibles | Teste avec les ressources du processus déployé |
Inspecte le contenu et l’apparence du PDF
La documentation actuelle des formats WeasyPrint indique que les images SVG sont rendues sous forme vectorielle dans le PDF. Cela ne signifie pas que tout fichier se terminant par .svg contient uniquement du dessin vectoriel : un SVG peut intégrer une image bitmap. Vérifie-le avec le diagnostic des images intégrées lorsque le résultat paraît encore pixellisé.
Pour cet exemple simple, nous avons inspecté les PDF enregistrés avec PyMuPDF 1.26.7 :
| Cas d’entrée | Enregistrements de dessin | Images intégrées | Cadre visible |
|---|---|---|---|
| Chaîne HTML sans base | 0 | 0 | Absent ; le texte alternatif apparaissait |
| Chaîne HTML avec le dossier comme base | 1 | 0 | 60 × 30 mm, ouverture préservée |
| HTML chargé par nom de fichier | 1 | 0 | Même résultat que la chaîne résolue |
Ces résultats concernent le cadre fourni, et non toutes les fonctionnalités SVG. Un tracé composé unique ne signifie pas non plus une forme visible unique : son sous-tracé intérieur définit l’ouverture.
Pour inspecter ton resolved.pdf, installe pymupdf==1.26.7 et exécute :
import pymupdf
with pymupdf.open("resolved.pdf") as document:
page = document[0]
print("Drawing records:", len(page.get_drawings()))
print("Embedded images:", len(page.get_images()))
for drawing in page.get_drawings():
box = drawing["rect"]
print("Bounds in mm:", box.width * 25.4 / 72,
box.height * 25.4 / 72)La référence des pages de PyMuPDF documente les méthodes d’inspection des dessins et des images. Ces nombres sont des diagnostics, pas un certificat de fidélité. Ouvre également le PDF : vérifie l’ouverture, les couleurs, les proportions et le lettrage à la taille réelle de livraison. Inspecte les dessins complexes fonctionnalité par fonctionnalité et refais les vérifications lorsque tu mets à jour le moteur de rendu.
Quand préparer d’abord un nouveau SVG
Lorsque le seul logo disponible est un PNG ou un JPG, le vectoriseur de logos PerfectVector peut préparer un SVG candidat avant son placement dans le document HTML. Inspecte les contours, les petites ouvertures et le lettrage dans un éditeur, puis teste le SVG dans la même chaîne WeasyPrint. Le guide de la vectorisation d’images explique ce qui change lorsque les pixels deviennent des tracés.
Conserve un SVG original modifiable lorsqu’il existe. Corrige sa référence de fichier ou sa mise en page au lieu de le tracer à nouveau. Les photographies peuvent rester matricielles, et le lettrage exact d’une marque peut nécessiter la police originale ou un redessin manuel. La vectorisation ne répare ni les fichiers serveur manquants, ni l’authentification, ni les fonctionnalités de rendu non prises en charge.
Si tu dois seulement convertir un SVG en sa propre page PDF, la méthode d’export CairoSVG couvre cette tâche plus limitée. WeasyPrint convient au cas du document HTML, où le dessin partage la page avec d’autres contenus.
FAQ
Pourquoi WeasyPrint crée-t-il un PDF sans mon logo SVG ? Un échec de chargement d’image peut laisser le reste du document affichable. Vérifie le journal des ressources et l’URL de l’image. Dans le test fourni, une chaîne HTML avec un chemin d’image relatif nécessitait une URL de base explicite.
Dois-je d’abord convertir le SVG en PNG ? Non. WeasyPrint accepte les images SVG. Garde les dessins vectoriels pris en charge au format SVG si c’est la sortie souhaitée, et vérifie le PDF enregistré. Un export matriciel est une solution de remplacement lorsque tu privilégies volontairement l’apparence à la géométrie vectorielle.
base_url change-t-il la taille imprimée du logo ? Non. Il fournit la base utilisée pour résoudre les URL relatives des ressources. Règle la taille de placement de l’image en CSS et vérifie séparément les dimensions et le viewBox du SVG.
Sources
- Référence de l’API WeasyPrint — Documente les entrées HTML, les URL de base, la sortie SVG et le comportement du zoom PDF.
- Premiers pas avec WeasyPrint — Couvre l’installation et la récupération des ressources, dont les limites d’authentification.
- Référence Page de PyMuPDF — Documente les méthodes d’inspection des dessins et des images intégrées utilisées dans l’exemple.
Tu n’as qu’un logo matriciel ? Prépare un SVG avec PerfectVector, inspecte ses formes et son lettrage, puis place-le dans ton HTML et vérifie son apparence et sa taille physique dans le PDF enregistré.
Plus depuis le blog

Images SVG Graphviz : des illustrations portables
Ajoute un SVG à un nœud Graphviz, examine sa référence d’image et teste les ressources complètes, le diagramme déplacé et une copie de livraison autonome.

SVG Matplotlib : garder graphique et logo en tracés
Exporte ton graphique Matplotlib en SVG, assemble des tracés de logo avec svgutils et vérifie les pixels intégrés, le placement et les polices du fichier livré.