PerfectVector
Von Irene Kim8 Min. Lesezeit

CairoSVG: SVG in richtiger Größe als PDF und PNG

Konvertiere SVG mit CairoSVG, wähle Ausgabebreite oder Skalierung, verstehe DPI und Containermaße und prüfe PNG-Pixel und PDF-Seitengröße vor der Weitergabe.

Auf dieser Seite

Verwende cairosvg.svg2png() für einen Rasterexport und cairosvg.svg2pdf() für ein PDF. Setze für eine bestimmte PNG-Breite output_width; verwende für eine proportionale Vergrößerung scale. parent_width liefert den Container, anhand dessen Prozentabmessungen aufgelöst werden. dpi steuert das Verhältnis zwischen Pixeln und physischen Einheiten. Eine Änderung kann deshalb PNG- und PDF-Größen unterschiedlich beeinflussen.

Das folgende Beispiel beginnt mit einem kleinen SVG-Emblem und prüft die Dateien, die jede Einstellung erzeugt. Es eignet sich für Designer, die Logoexporte automatisieren, und Entwickler, die Grafiken für Dokumente vorbereiten. CairoSVG rendert bestehende SVG-Inhalte. Es zeichnet kein PNG-Logo in bearbeitbare Pfade nach.

Beginne mit einem eigenständigen SVG

Wir führten diese Beispiele mit Python 3.12.11 und CairoSVG 2.9.1 aus. Installiere den Konverter in der festgelegten Version in einer Projektumgebung:

python -m pip install "CairoSVG==2.9.1"

CairoSVG benötigt außerdem die native Cairo-Bibliothek. Wenn Installation oder Import scheitern, folge den Betriebssystemhinweisen in der Installationsdokumentation.

Speichere dieses eigene Emblem aus drei Pfaden als emblem.svg. An der quadratischen Öffnung fällt eine fehlende Füllregel leicht auf, und der schmale Balken dient zur Prüfung kleiner Details. Das ist von Hand erstellte Demonstrationsgrafik, keine PerfectVector-Konvertierung.

<svg xmlns="http://www.w3.org/2000/svg"
     width="240" height="120" viewBox="0 0 240 120">
  <path fill="#176b63" fill-rule="evenodd"
        d="M20 100 V20 H100 V100 Z M40 40 V80 H80 V40 Z"/>
  <path fill="#e5a43a" d="M110 100 L160 20 L210 100 Z"/>
  <path fill="#24435d" d="M220 20 H230 V100 H220 Z"/>
</svg>

Die Abmessungen des Wurzelelements beschreiben den Ausgabe-Viewport. Die viewBox beschreibt das interne Koordinatenrechteck der Grafik. Hier haben beide dasselbe Verhältnis von 2:1. Behalte diese Beziehung bewusst bei, wenn du das Beispiel an dein Logo anpasst.

Exportiere ein Original in der benötigten Größe

Speichere dies als export_emblem.py neben dem SVG und führe dann python export_emblem.py aus:

import cairosvg
 
cairosvg.svg2png(
    url="emblem.svg",
    write_to="emblem-480.png",
    output_width=480,
)
cairosvg.svg2pdf(
    url="emblem.svg",
    write_to="emblem.pdf",
)

Unser PNG hatte 480 × 240 Pixel. Die PDF-Seite maß 180 × 90 Punkte, entsprechend 2.5 × 1.25 Zoll. Das sind Messwerte des bereitgestellten Testbeispiels, keine Abmessungen, die du bei jedem SVG erwarten solltest.

Die entsprechenden Kommandozeilenbefehle sind:

cairosvg emblem.svg --output-width 480 -o emblem-480.png
cairosvg emblem.svg -o emblem.pdf

Die API- und Kommandozeilenreferenz von CairoSVG dokumentiert Eingabedateinamen über url, SVG-Bytes über bytestring und Dateiausgabe über write_to. In der CLI wählt die Endung des Ausgabedateinamens das Format.

Illustration eines geometrischen Emblems, das in zwei proportional ähnliche Exporte auf unterschiedlich großen Zeichenflächen verzweigt
Illustration der Exportentscheidung: Behalte ein Vektororiginal und wähle dann die für jede Ausgabe benötigten Abmessungen. Die gemessenen CairoSVG-Ergebnisse stehen unten.

Wähle die Einstellung, die zum Problem passt

Die ähnlich benannten Optionen beantworten unterschiedliche Fragen. Die CairoSVG-Größenreferenz unterscheidet den übergeordneten Container von den angeforderten Ausgabeabmessungen.

Deine AnforderungPython-OptionCLI-OptionWas du prüfen solltest
Ein PNG genau 480 Pixel breit erzeugenoutput_width=480--output-width 480Höhe und Grafikproportionen
Aufgelöste Ausgabeabmessungen verdoppelnscale=2--scale 2Beide Abmessungen verdoppelt
Als Prozent angegebene Wurzelbreite oder -höhe auflösenparent_width, parent_height--width, --heightProzentanteil des übergebenen Containers
Physische Einheiten wie Zoll interpretierendpi--dpiPNG-Pixelabmessungen und physische PDF-Größe separat

Bei unserer in Pixeln bemaßten Quelle führten wir jede Option unabhängig aus:

EinstellungenPNG-AbmessungenPDF-Seitenabmessungen
Standardwerte240 × 120 px180 × 90 pt
output_width=480480 × 240 px360 × 180 pt
scale=2480 × 240 px360 × 180 pt
dpi=192240 × 120 px90 × 45 pt

Die letzte Zeile ist die Falle: Eine Verdopplung der DPI gab diesem pixelbemaßten SVG nicht mehr PNG-Pixel. Dieselben Pixelabmessungen nahmen im PDF weniger physischen Platz ein. Verwende eine Ausgabeabmessung, wenn deine Anforderung eine Pixelanzahl ist.

Wenn du beide Ausgabeabmessungen angibst, legst du das Rechteck der Zeichenfläche fest; das garantiert keinen eng ausgefüllten Logorahmen. Die SVG-Seitenverhältnisregeln und Leerflächen innerhalb der viewBox bleiben relevant. Beginne mit einer einzelnen Ausgabeabmessung, wenn du die Originalproportionen möchtest, und prüfe anschließend das Ergebnis.

Prozentabmessungen benötigen einen übergeordneten Container

Für eine Kopie des Testbeispiels, deren Wurzelelement width="50%" height="50%" verwendet, übergibt dieser Aufruf einen übergeordneten Container von 960 × 480 Pixeln:

cairosvg.svg2png(
    url="emblem-percent.svg",
    parent_width=960,
    parent_height=480,
    write_to="emblem-percent.png",
)

Unsere Ausgabe maß 480 × 240 Pixel: die halbe Breite und die halbe Höhe des übergeordneten Containers. Das erklärt, warum parent_width=480 nicht mit output_width=480 austauschbar ist.

Wenn CairoSVG meldet, dass die SVG-Größe undefiniert ist, prüfe zuerst die Wurzelabmessungen. Gib dem Dokument positive, zur Nutzung passende Abmessungen oder übergib die Abmessungen des übergeordneten Containers, wenn Prozentwerte davon abhängen. Leite die gewünschte Seitengröße nicht daraus ab, wie groß ein Browser die Grafik zufällig anzeigt.

Physische Abmessungen verhalten sich anders

Ändere das ursprüngliche Wurzelelement zu width="2.5in" height="1.25in" und behalte seine viewBox. In unserem Test erzeugte dpi=96 ein PNG mit 240 × 120 und dpi=192 eines mit 480 × 240. Beide PDFs blieben bei 180 × 90 Punkten.

Hier definiert die Quelle eine physische Größe. Mehr Pixel pro Zoll erhöhen deshalb die Rasterauflösung, während die physische PDF-Seitengröße erhalten bleibt. Dasselbe Prinzip erlaubt einer bewusst erstellten Seite, Millimeter oder Zoll zu verwenden. Prüfe den Seitenrahmen des exportierten PDFs, statt anzunehmen, dass eine hohe Pixelanzahl eine A4- oder Letter-Seite bedeutet.

Wenn das Logo in einem Bericht mit Text, Rändern und mehreren Elementen platziert werden soll, verwende einen Dokumentlayoutschritt. Unser Leitfaden zur SVG-Platzierung mit ReportLab behandelt die direkte PDF-Erstellung; die Ressourcen- und Größenprüfungen für WeasyPrint behandeln HTML-Dokumente.

Prüfe den Export und was Vektor geblieben ist

Wir lasen die PNG-Header mit Pillow und die PDF-Seitenrahmen und Inhaltsstreams mit pypdf 6.10.0. Jedes der vier PDFs aus der Pixelquelle enthielt Zeichenpfadoperationen und keine Seitenbilder. Das bestätigt Vektorgeometrie für dieses einfache Testbeispiel ohne Bilder. Es belegt keine vollständige Originaltreue für ein beliebiges SVG.

Installiere zur Prüfung deiner eigenen Ausgabeabmessungen pillow und pypdf in derselben Umgebung und führe Folgendes aus:

from PIL import Image
from pypdf import PdfReader
 
with Image.open("emblem-480.png") as image:
    print("PNG pixels:", image.size)
 
page = PdfReader("emblem.pdf").pages[0]
print("PDF points:", float(page.mediabox.width),
      float(page.mediabox.height))
print("Page images:", len(page.images))

Die PageObject-Referenz beschreibt mediabox und images. Die Bildanzahl ist eine nützliche Diagnose, kann aber nicht beweisen, dass jede Form, Schrift oder jeder Effekt korrekt erhalten geblieben ist.

Vor der Weitergabe:

  1. Öffne PNG und PDF und vergleiche das Emblem mit dem SVG. Prüfe Öffnung, Dreieck, Balken und Ränder.
  2. Prüfe die Pixelabmessungen des PNGs und die physischen Abmessungen des PDFs unabhängig voneinander.
  3. Prüfe die Grafik in der vorgesehenen Nutzungsgröße, einschließlich schmaler Zwischenräume und kleiner Details.
  4. Behalte das ursprüngliche SVG und wiederhole diese Prüfungen nach Änderungen oder einem Konverterupgrade.

CairoSVGs Seite zur SVG-Unterstützung erklärt, dass Vektorausgabe nach Möglichkeit erhalten bleibt. Eingebettete Rasterbilder bleiben Rasterinhalt. Wenn deine Datei ein PNG in einer SVG-Hülle enthält, hilft dir die Diagnose eingebetteter Bilder, das vor dem Export zu erkennen.

CairoSVG ist ein statischer Renderer. Animation, Skripting, fortgeschrittenes Textlayout und viele Filter liegen außerhalb des unterstützten Workflows. Seine Dokumentation nennt nur feOffset, feBlend und feFlood als unterstützte Filter. Vergleiche bei Grafiken, die von anderen Effekten abhängen, das Ergebnis sorgfältig oder exportiere über eine Anwendung, die diese Funktionen unterstützt. Ein erfolgreicher Konvertierungsaufruf allein reicht nicht aus.

Rekonstruiere ein Vektororiginal nur, wenn die Quelle es benötigt

Wenn dein Logo nur noch als PNG oder JPG vorhanden ist, kann PerfectVector vor dem CairoSVG-Export den vorgelagerten Raster-zu-SVG-Schritt übernehmen. Prüfe rekonstruierte Formen, kleine Öffnungen und Markenschrift in einem Editor und speichere dann ein eigenständiges SVG-Original. Unser Workflow zur Logo-Vektorisierung erklärt diese Prüfung.

Ein vorhandenes bearbeitbares SVG kann direkt in die Exportphase gehen. Es in PNG umzuwandeln und erneut nachzuzeichnen würde nützliche Quellgeometrie verwerfen. Fotos können Rasterbilder bleiben, wenn das der gewünschte Inhalt ist.

Bei einem reinen Rasterlogo probiere dein eigenes Bild in PerfectVector aus, prüfe Konturen und Öffnungen des SVGs und kontrolliere dann sowohl Pixelabmessungen als auch physische Seitengröße deiner CairoSVG-Exporte.

FAQ

Warum bleibt mein PNG beim Ändern der DPI gleich groß? Wenn das SVG-Wurzelelement Pixelabmessungen verwendet, verändert DPI nicht unbedingt die PNG-Pixelanzahl. In diesem Beispiel blieb ein SVG mit 240 mal 120 Pixeln bei 192 DPI gleich groß. Verwende output_width oder scale, wenn du mehr Ausgabepixel benötigst.

Ist die Breite des übergeordneten Containers dasselbe wie die Ausgabebreite? Nein. parent_width liefert den Container, anhand dessen Prozentabmessungen aufgelöst werden. output_width fordert die endgültige Ausgabebreite an. Eine Wurzelbreite von 50% mit parent_width 960 wurde im Beispiel zu 480 Pixeln aufgelöst.

Erzeugt CairoSVG immer ein vollständig vektorbasiertes PDF? Nein. CairoSVG erhält Vektorausgabe nach Möglichkeit, aber ein SVG kann Rasterbilder und nicht unterstützte Funktionen enthalten. Prüfe Inhalt und Darstellung des PDFs, statt die Dateiendung als Beweis zu behandeln.

Quellen

  1. CairoSVG-Dokumentation — Beschreibt Installation, Konvertierungs-APIs, Größeneinstellungen und Renderinggrenzen.
  2. CairoSVG-Unterstützung für SVG 1.1 — Erklärt Vektorerhalt, eingebettete Bilder und nicht unterstützte Funktionen.
  3. pypdf-PageObject-Referenz — Dokumentiert die Seitenrahmen- und Bildschnittstellen zur PDF-Prüfung.

Mehr aus dem Blog

Starte mit einer sauberen SVG,
die leichter zu bearbeiten ist