WeasyPrint-SVG-Bilder: Fehlende Logos im PDF beheben
Behebe fehlende SVG-Logos in WeasyPrint-PDFs mit korrekter Basis-URL und CSS-Größen. Prüfe das gespeicherte PDF auf Vektorpfade, Proportionen und Grafik.
Auf dieser Seite
WeasyPrint kann ein SVG über ein HTML-Bildelement in einem PDF platzieren. Wenn das Logo verschwindet, sobald du HTML als Zeichenfolge übergibst, prüfe zuerst die Bild-URL: Ein relativer Pfad braucht eine Basis-URL. Sobald die Datei geladen wird, legst du ihre Druckgröße per CSS fest und kontrollierst das gespeicherte PDF. Die aktuelle WeasyPrint-API-Referenz dokumentiert diese Anforderung an base_url.
Das folgende Beispiel reproduziert diesen Fall mit einem eigens erstellten rahmenförmigen Logo. Es prüft auch, ob das korrigierte PDF Vektorzeichengeometrie in der gewünschten Größe enthält. Wenn du bereits ein SVG hast, beginne mit dieser Datei. Vektorisierung kommt erst ins Spiel, wenn die Quellgrafik als Pixel vorliegt.
Prüfe das Laden, bevor du die Grafik änderst
Ein PDF kann erstellt werden, obwohl sein Logo fehlt. Prüfe die Ressourcenwarnung, korrigiere den Bildpfad und rendere dasselbe SVG erneut, bevor du seine Formen bearbeitest oder es in ein anderes Format umwandelst.
Reproduziere das fehlende SVG mit einem kleinen Dokument
Wir haben mit Python 3.13.9 und WeasyPrint 70.0 getestet. Verwende eine Projektumgebung und installiere die festgelegte Version:
python -m pip install "weasyprint==70.0"
python -m weasyprint --infoWeasyPrint benötigt außerdem native Bibliotheken, darunter Pango. Folge den Installationsanweisungen für dein Betriebssystem, wenn der Import oder der Versionsbefehl fehlschlägt. Eine fehlende native Bibliothek ist ein anderes Problem als ein fehlendes Logo.
Erstelle diese Ordnerstruktur:
example/
render.py
assets/
logo.svgSpeichere diese eigens erstellte Beispielgrafik als assets/logo.svg. Die Öffnung in der Mitte gibt dir mehr zu prüfen als ein ausgefülltes Rechteck. Es handelt sich um von Hand erstellte Geometrie, nicht um eine PerfectVector-Konvertierung.
<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>Schreibe Folgendes in 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")Führe python render.py aus. In unserem ersten PDF fehlte der Rahmen und der Alternativtext des Bildes erschien. Das Protokoll enthielt:
Relative URI reference without a base URI: assets/logo.svgDas zweite PDF zeigte den blaugrünen Rahmen mit intakter Öffnung. Beide Aufrufe erzeugten eine Datei; die bloße Existenz eines PDF war deshalb kein brauchbarer Erfolgsnachweis.
Gib relativen Pfaden einen festen Ausgangsordner
assets/logo.svg bezeichnet eine Datei relativ zu einem anderen Ort. base_url im zweiten Aufruf liefert diesen Ausgangspunkt. root.as_uri() erstellt eine absolute Datei-URI; der abschließende Schrägstrich macht sie zur Verzeichnisbasis. Das Logo bleibt im selben assets-Ordner und der SVG-Inhalt ändert sich nicht.
Durch Path(__file__) bleibt das Beispiel auch dann an den Ordner des Skripts gebunden, wenn du es aus einem anderen Arbeitsverzeichnis startest. In einem Notebook verwendest du stattdessen einen expliziten Projektordner, da __file__ dort normalerweise nicht verfügbar ist.

Es gibt einen weiteren nützlichen Kontrolltest. Speichere das HTML als invoice.html neben render.py und lade die Datei selbst:
HTML(filename=str(root / "invoice.html")).write_pdf(
root / "from-file.pdf"
)WeasyPrint kann aus einem Eingabedateinamen oder einer URL eine Basis ableiten. Unser dateibasierter Test erzeugte denselben Rahmen wie der Fall mit expliziter Basis. Eine HTML-Zeichenfolge hat keinen zugehörigen Dateinamen, aus dem diese Basis abgeleitet werden könnte. Diese Eingabemodi und ihre Regeln zur Basisauflösung sind im HTML-Konstruktor dokumentiert.
Bei einem Bild hinter einer Anmeldung reicht eine korrekte URL möglicherweise nicht aus. Laut Dokumentation zu URL-Fetchern bietet der Standard-HTTP-Client weder Cookies noch Authentifizierung. Verwende die freigegebene Ressourcenabfrage deiner Anwendung und teste sie in der Umgebung, die das PDF erzeugt. Geh nicht davon aus, dass ein in deinem angemeldeten Browser sichtbares Logo auch für den PDF-Prozess erreichbar ist.
Lege die Bildgröße unabhängig von der PDF-Seitengröße fest
Das Beispiel verwendet @page für das A4-Blatt und die Ränder, während .logo die Bildbreite auf 60 mm setzt. Durch das Seitenverhältnis von 2:1 ist es mit height: auto 30 mm hoch. In unserem gespeicherten PDF maß der Rahmen 60 × 30 mm und begann jeweils 20 mm vom oberen und linken Seitenrand entfernt.
Hier füllt die Zeichnung ihre gesamte viewBox. Dein Logo kann innerhalb dieses Rechtecks Leerraum enthalten, sodass ein 60 mm breiter Bildrahmen eine sichtbar schmalere Bildmarke enthält. Prüfe die SVG-Zeichenfläche, bevor du das mit einer willkürlich größeren CSS-Breite ausgleichst. Der Leitfaden zur SVG-Importgröße erklärt diesen Unterschied genauer.
Lass write_pdf() beim Standardwert zoom=1, wenn du physische Abmessungen prüfst. Die PDF-Ausgabereferenz von WeasyPrint warnt, dass eine Änderung von zoom auch physische CSS-Einheiten und benannte Seitengrößen skaliert.
| Was du siehst | Erste Prüfung | Nächster Schritt |
|---|---|---|
| Alternativtext ersetzt das Logo | Bild-URL und Ressourcenprotokoll | Gültige Basis-URL oder erreichbare absolute URL angeben |
| Logo erscheint in falscher Größe | CSS-Breite und Seitenverhältnis der Quelle | Physische Breite festlegen und SVG-Zeichenfläche prüfen |
| Ein Teil der Grafik fehlt | Quellgrenzen und konkrete SVG-Funktion | Auf ein kleines fehlschlagendes Beispiel reduzieren und exportiertes PDF vergleichen |
| Lokales Rendern funktioniert, auf dem Server nicht | Verfügbare Dateien, Schriften und URL-Zugriff | Mit den Ressourcen des bereitgestellten Prozesses testen |
Prüfe Inhalt und Darstellung des PDF
Laut aktueller WeasyPrint-Formatdokumentation werden SVG-Bilder in der PDF-Ausgabe als Vektoren gerendert. Das bedeutet nicht, dass jede Datei mit .svg-Endung vollständig aus Vektorgrafik besteht: Ein SVG kann eine eingebettete Bitmap enthalten. Prüfe das mit der Diagnose eingebetteter Bilder, wenn das Ergebnis weiterhin verpixelt aussieht.
Für diese einfache Testdatei haben wir die gespeicherten PDFs mit PyMuPDF 1.26.7 untersucht:
| Eingabefall | Zeichnungseinträge | Eingebettete Bilder | Sichtbarer Rahmen |
|---|---|---|---|
| HTML-Zeichenfolge ohne Basis | 0 | 0 | Fehlte; Alternativtext erschien |
| HTML-Zeichenfolge mit Ordnerbasis | 1 | 0 | 60 × 30 mm, Öffnung erhalten |
| HTML über Dateinamen geladen | 1 | 0 | Gleiches Ergebnis wie bei der aufgelösten Zeichenfolge |
Diese Ergebnisse gelten für den bereitgestellten Rahmen, nicht für jede SVG-Funktion. Ein zusammengesetzter Pfad bedeutet außerdem nicht eine einzelne sichtbare Form: Sein innerer Teilpfad definiert die Öffnung.
Um deine resolved.pdf zu prüfen, installiere pymupdf==1.26.7 und führe Folgendes aus:
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)Die Seitenreferenz von PyMuPDF dokumentiert die Methoden zur Prüfung von Zeichnungen und Bildern. Diese Zählwerte sind Diagnosehilfen, kein Nachweis der Wiedergabetreue. Öffne auch das PDF: Prüfe Öffnung, Farben, Proportionen und Schrift in der tatsächlichen Ausgabegröße. Untersuche bei komplexen Grafiken jede Funktion einzeln und wiederhole die Prüfungen nach einem Renderer-Upgrade.
Wann du zuerst ein neues SVG vorbereiten solltest
Wenn das einzige verfügbare Logo ein PNG oder JPG ist, kann PerfectVectors Logo-Vektorisierer einen SVG-Kandidaten vorbereiten, bevor du ihn im HTML-Dokument platzierst. Prüfe Konturen, kleine Öffnungen und Schrift in einem Editor und teste das SVG anschließend durch dieselbe WeasyPrint-Verarbeitung. Der Leitfaden zur Bildvektorisierung erklärt, was sich ändert, wenn Pixel zu Pfaden werden.
Behalte ein ursprüngliches bearbeitbares SVG, wenn es eines gibt. Korrigiere seinen Dateiverweis oder das Layout, statt es erneut nachzuzeichnen. Fotos können Rasterbilder bleiben, und exakte Markenschrift kann die ursprüngliche Schriftart oder eine manuelle Neuzeichnung erfordern. Vektorisierung repariert keine fehlenden Serverdateien, Authentifizierung oder nicht unterstützte Darstellungsfunktionen.
Wenn du ein SVG nur in eine eigene PDF-Seite umwandeln möchtest, behandelt der CairoSVG-Exportablauf diese kleinere Aufgabe. WeasyPrint passt zum HTML-Dokument, in dem die Grafik mit anderen Inhalten auf einer Seite steht.
FAQ
Warum erstellt WeasyPrint ein PDF ohne mein SVG-Logo? Wenn ein Bild nicht geladen werden kann, bleibt der Rest des Dokuments möglicherweise renderbar. Prüfe das Ressourcenprotokoll und die Bild-URL. Im bereitgestellten Test benötigte eine HTML-Zeichenfolge mit relativem Bildpfad eine explizite Basis-URL.
Muss ich das SVG zuerst in PNG umwandeln? Nein. WeasyPrint akzeptiert SVG-Bilder. Behalte unterstützte Vektorgrafik als SVG, wenn das die beabsichtigte Ausgabe ist, und prüfe das gespeicherte PDF. Ein Rasterexport ist eine Alternative, wenn du bewusst der Darstellung Vorrang vor Vektorgeometrie gibst.
Ändert base_url die Druckgröße des Logos? Nein. Es liefert die Basis zum Auflösen relativer Ressourcen-URLs. Lege die Platzierungsgröße des Bildes per CSS fest und prüfe die Abmessungen und viewBox des SVG separat.
Quellen
- WeasyPrint-API-Referenz — Dokumentiert HTML-Eingaben, Basis-URLs, SVG-Ausgabe und das PDF-Zoomverhalten.
- WeasyPrint: Erste Schritte — Behandelt Installation und Ressourcenabfrage einschließlich Authentifizierungsgrenzen.
- PyMuPDF-Seitenreferenz — Dokumentiert die im Beispiel verwendeten Methoden zum Prüfen von Zeichnungen und eingebetteten Bildern.
Hast du nur ein Rasterlogo? Bereite mit PerfectVector ein SVG vor, prüfe seine Formen und Schrift, platziere es dann in deinem HTML und kontrolliere seine Darstellung und physische Größe im gespeicherten PDF.
Mehr aus dem Blog

Graphviz-SVG-Bilder: Knotengrafiken portabel halten
Füge SVG-Grafiken in Graphviz-Knoten ein, prüfe Bildreferenzen und vergleiche ein vollständiges Asset-Paket mit einem verschobenen Diagramm und einer eigenständigen Kopie.

Matplotlib-SVG: Diagramm und Logo als Pfade erhalten
Exportiere dein Matplotlib-Diagramm als SVG, ergänze separate Logopfade mit svgutils und prüfe die fertige Datei auf eingebettete Pixel, Platzierung und Schriftänderungen.