PerfectVector
Von Irene Kim8 Min. Lesezeit

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 --info

WeasyPrint 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.svg

Speichere 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.svg

Das 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.

Illustration einer SVG-Grafik in einem Ordner, die durch einen Pfeil mit derselben Grafik auf einer Dokumentseite verbunden ist
Illustration der Ressourcenauflösung: Das Dokument braucht einen Weg zur SVG-Datei, bevor es die Grafik platzieren kann.

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 siehstErste PrüfungNächster Schritt
Alternativtext ersetzt das LogoBild-URL und RessourcenprotokollGültige Basis-URL oder erreichbare absolute URL angeben
Logo erscheint in falscher GrößeCSS-Breite und Seitenverhältnis der QuellePhysische Breite festlegen und SVG-Zeichenfläche prüfen
Ein Teil der Grafik fehltQuellgrenzen und konkrete SVG-FunktionAuf ein kleines fehlschlagendes Beispiel reduzieren und exportiertes PDF vergleichen
Lokales Rendern funktioniert, auf dem Server nichtVerfügbare Dateien, Schriften und URL-ZugriffMit 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:

EingabefallZeichnungseinträgeEingebettete BilderSichtbarer Rahmen
HTML-Zeichenfolge ohne Basis00Fehlte; Alternativtext erschien
HTML-Zeichenfolge mit Ordnerbasis1060 × 30 mm, Öffnung erhalten
HTML über Dateinamen geladen10Gleiches 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

  1. WeasyPrint-API-Referenz — Dokumentiert HTML-Eingaben, Basis-URLs, SVG-Ausgabe und das PDF-Zoomverhalten.
  2. WeasyPrint: Erste Schritte — Behandelt Installation und Ressourcenabfrage einschließlich Authentifizierungsgrenzen.
  3. 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

Starte mit einer sauberen SVG,
die leichter zu bearbeiten ist