Ratgeber · Engine & Libraries
Canvas-Rendering und DPI: Wie PDF-Seiten zu JPG/PNG werden
Eine PDF-Seite ist Vektor. Ein JPG oder PNG ist Pixel. Dazwischen liegt das HTML5-Canvas und ein bisschen Mathematik. Dieser Artikel erklärt den Zusammenhang zwischen scale-Faktor und DPI, wann JPG einen weißen Hintergrund braucht und warum PNG bei scharfen Kanten gewinnt.
Wer eine PDF-Datei in ein JPG oder PNG umwandelt, schaut dem Browser bei einer Vektor-zu-Pixel-Konvertierung zu. PDF speichert Inhalte als mathematische Beschreibung, JPG und PNG als Pixel-Raster. Dazwischen sitzt das HTML5-Canvas-Element. Auf pdfkonvertieren.de läuft genau dieser Prozess clientseitig ab. Wie er funktioniert, wo die Knöpfe sind und welche Auflösung wann sinnvoll ist, erklären wir hier.
Vom PDF-Punkt zum Pixel
PDF nutzt als Maßeinheit den PostScript-Punkt, definiert als ein Zweiundsiebzigstel Zoll. Diese Konvention stammt aus der Druckindustrie und ist seit der ersten PostScript-Spezifikation von 1985 unverändert. Eine A4-Seite hat in PDF-Punkten genau 595 × 842, weil 210 mm und 297 mm bei 72 dpi diese Pixel-Zahl ergeben.
Wenn pdfjs-dist eine Seite rendern soll, ruft man zuerst page.getViewport({ scale: 1 }) auf. Das Viewport-Objekt enthält Breite und Höhe in Pixeln. Bei scale 1 bekommt man genau die PDF-Punkt-Dimensionen zurück, also 595 × 842 für A4. Setzt man scale 2, verdoppeln sich die Dimensionen auf 1190 × 1684, und das gerenderte Bild hat doppelte DPI: 144 statt 72.
| scale-Faktor | Dimensionen A4 (px) | DPI | Pixel pro Seite | Render-Zeit relativ |
|---|---|---|---|---|
| 1 | 595 × 842 | 72 | 0,5 Mio | 1× |
| 2 | 1190 × 1684 | 144 | 2,0 Mio | 4× |
| 3 | 1785 × 2526 | 216 | 4,5 Mio | 9× |
| 4 | 2380 × 3368 | 288 | 8,0 Mio | 16× |
Die Render-Zeit wächst quadratisch, weil jeder Pixel berechnet werden muss. Das ist auch der Grund, warum wir scale 2 als Default verwenden: Die Datei ist groß genug für scharfe Bildschirmdarstellung, aber klein genug, dass auch 30-Seiten-PDFs unter zehn Sekunden rendern.
Canvas vorbereiten und Hintergrund füllen
Vor dem Rendern müssen wir das Canvas-Element auf die richtige Größe setzen. Das geht über die width- und height-Properties des HTMLCanvasElement, nicht über CSS. CSS skaliert nur die Darstellung, ändert aber nicht die Pixel-Anzahl. Wer beides verwechselt, bekommt verschwommene Bilder.
Der entscheidende Schritt für die spätere JPG-Konvertierung: das Canvas mit weißem Hintergrund füllen.
const canvas = document.createElement('canvas');
const viewport = page.getViewport({ scale: 2 });
canvas.width = viewport.width;
canvas.height = viewport.height;
const ctx = canvas.getContext('2d');
ctx.fillStyle = '#ffffff';
ctx.fillRect(0, 0, canvas.width, canvas.height);
await page.render({ canvasContext: ctx, viewport }).promise;
Wer diesen fillRect-Aufruf vergisst, bekommt bei JPG-Export schwarze oder grauliche Bereiche an Stellen, wo die PDF-Seite transparent war. Bei PNG ist das kein Problem, weil PNG den Alpha-Channel beibehält.
JPG hat keinen Alpha-Channel
Das JPEG-Format ist standardisiert in ISO/IEC 10918-1 aus 1992. Die Spec definiert kein Alpha-Channel, nur YCbCr- oder RGB-Farben. Wenn der Browser ein Canvas mit transparenten Pixeln via canvas.toBlob('image/jpeg') exportiert, muss er entscheiden, was er mit den transparenten Pixeln macht. Die WHATWG-Spec schreibt vor: alle nicht-undurchsichtigen Farben werden mit Schwarz multipliziert. Das ergibt in der Praxis dunkle Streifen oder ganze schwarze Flächen.
Daher fixieren wir den Hintergrund vor dem Rendering auf Weiß. Das ist gleichzeitig das Standard-Verhalten der meisten PDF-Reader: leere Bereiche werden weiß dargestellt.
Das toBlob-Verfahren erlaubt einen Quality-Parameter zwischen 0.0 und 1.0:
canvas.toBlob((blob) => {
// blob enthält das JPG
}, 'image/jpeg', 0.92);
Quality 0.92 ist unser Default. Bei 1.0 wird die Datei merklich größer, der visuelle Gewinn ist unter normalen Bedingungen aber nicht wahrnehmbar. Unter 0.85 beginnen Kompressions-Artefakte sichtbar zu werden, vor allem an Schrift-Kanten.
PNG für scharfe Kanten
PNG ist seit RFC 2083 aus 1996 standardisiert, ursprünglich als patentfreier Ersatz für GIF. Das Format ist verlustfrei und unterstützt einen 8-bit-Alpha-Channel. Bei PDFs mit Strichzeichnungen, technischen Diagrammen, Tabellen oder Text auf farbigem Hintergrund liefert PNG sichtbar bessere Ergebnisse, weil die Kompression keine Kanten weichzeichnet.
Der Trade-off ist die Dateigröße. Ein typisches A4-PDF mit Fließtext und einem Foto wiegt:
| Format | Quality | Größe pro Seite (scale 2) | Anwendung |
|---|---|---|---|
| JPG | 0.85 | ~120 KB | Fotos, schnelle Vorschau |
| JPG | 0.92 | ~180 KB | Standard, ausgewogen |
| JPG | 1.0 | ~340 KB | Fotos in Maximal-Qualität |
| PNG | verlustfrei | ~520 KB | Strichzeichnungen, Diagramme |
Für unsere PDF-zu-JPG-Engine bieten wir Quality-Stufen 0.7, 0.85 und 1.0 an. Für PDF-zu-PNG gibt es nur eine Qualitätsstufe, weil PNG kein Quality-Setting kennt, sondern nur einen Kompressions-Level für die DEFLATE-Komprimierung.
DPI für verschiedene Anwendungsfälle
Bildschirme zeigen heute meist zwischen 100 und 220 Pixel pro Zoll an. Ein altes 24-Zoll-Display mit Full-HD-Auflösung hat etwa 92 DPI, ein 27-Zoll-4K-Monitor hat 163 DPI, ein 13-Zoll-MacBook-Pro-Retina hat 227 DPI. Für saubere Darstellung sollte das gerenderte JPG mindestens so viele Pixel haben wie das Display.
Für Druck gilt der Industrie-Standard von 300 DPI. Wer auf einem Tintenstrahl- oder Laserdrucker druckt, sollte mindestens 200 DPI verwenden. Großformat ab A2 (Plakate, Banner) kommt mit 150 DPI aus, weil der Betrachtungsabstand größer ist.
OffscreenCanvas und Worker-Rendering
Seit Chrome 69 und Firefox 105 gibt es OffscreenCanvas, eine Canvas-Variante, die in einem Web Worker laufen kann. Das ist relevant, weil normale HTMLCanvasElement-Instanzen nur im Main-Thread existieren. Mit OffscreenCanvas lässt sich das Rendering komplett aus dem UI-Thread auslagern.
Für pdfjs-dist ist das aktuell nur eingeschränkt nutzbar, weil die page.render-API einen normalen Canvas-Context erwartet. In Version 4 des Libraries kam aber experimentelle OffscreenCanvas-Unterstützung, die wir bei größeren PDFs einsetzen, um die UI während Multi-Seiten-Rendering komplett flüssig zu halten. Safari unterstützt OffscreenCanvas erst seit Version 16.4 (März 2023), für ältere Safaris fallen wir auf Main-Thread-Rendering zurück.
Farbprofil und Farbtreue
PDF kann ICC-Farbprofile einbetten (CMYK, sRGB, Adobe RGB, ProPhoto). Wenn wir auf Canvas rendern, geht das Profil verloren, weil Canvas immer mit sRGB arbeitet. Bei Standard-Office-PDFs ist das kein Problem, weil sie ohnehin sRGB oder unprofiliertes RGB nutzen. Bei professionellen Druck-PDFs mit CMYK-Profilen kann die Konvertierung allerdings leichte Farbverschiebungen verursachen, vor allem bei satten Rottönen und Hautfarben.
pdfjs-dist macht intern eine ICC-zu-sRGB-Konvertierung, die für die meisten Anwendungsfälle ausreicht. Für hochwertige Druck-Workflows ist eine Browser-Konvertierung nicht die richtige Wahl, dort sind dedizierte Tools mit echtem Color-Management (Adobe Acrobat Pro mit ICC-Bibliothek, GhostScript mit -sColorConversionStrategy) besser geeignet. Für Bildschirm-Vorschauen, Web-Thumbnails und Standard-Konvertierungen ist die sRGB-Vereinfachung kein erkennbares Problem.
Wo canvas.toBlob zur Engpass-Stelle wird
Bei großen PDFs mit 50 oder mehr Seiten wird canvas.toBlob zur Engpass-Stelle. Die Funktion ist asynchron, blockiert aber kurz den Haupt-Thread während der Encoding-Phase. Bei scale 4 und 50 Seiten reden wir über 800 Megapixel insgesamt, die JPG-Encoder verarbeiten müssen. Auf älteren CPUs kann das mehrere Minuten dauern.
Wir lösen das auf zwei Wegen: erstens lagern wir das PDF-Rendering selbst in den pdfjs-dist-Worker aus, sodass die Seiten parallel zur UI gerendert werden. Zweitens verarbeiten wir die Seiten sequenziell, nicht parallel, damit der Browser nicht plötzlich 50 Canvases mit 8 Megapixeln im Speicher hält. Während Seite 3 encodiert wird, läuft das Render-Job für Seite 4 schon im Worker, sodass die CPU permanent ausgelastet ist, ohne dass der Browser an Memory-Limits stößt.
Anti-Aliasing und Subpixel-Rendering
Der Canvas-Renderer von pdfjs-dist macht standardmäßig Anti-Aliasing für Vektor-Grafiken und Text. Das gibt scharfe Kanten ohne Treppen-Effekt. In Firefox und Chrome wird zusätzlich Subpixel-Anti-Aliasing eingesetzt, was bei normalen Bildschirmen die wahrgenommene Schärfe erhöht. Das hat einen praktischen Nebeneffekt: wenn der gerenderte Canvas mit einem nicht ganzzahligen Scale-Faktor angezeigt wird, kann das Anti-Aliasing zu Unschärfe führen.
Wir nutzen für Vorschau-Renderings den Browser-Pixel-Ratio (window.devicePixelRatio). Auf einem 4K-Monitor mit Pixel-Ratio 2 rendern wir doppelt so hoch wie das CSS-Maß und skalieren via CSS-Width zurück. So bleibt die Vorschau auf HiDPI-Displays gestochen scharf.
Speicher-Limits in mobilen Browsern
Mobile Browser (Safari iOS, Chrome Android) haben deutlich engere Memory-Limits als Desktop-Browser. iOS Safari erlaubt zum Beispiel maximal etwa 380 MB pro Tab auf älteren Geräten (iPhone 11 und früher), neuere Geräte bekommen mehr. Ein 50-Seiten-PDF in scale 4 mit Canvas-Backing würde diese Grenze schnell sprengen.
Wir prüfen daher User-Agent und verfügbaren Memory (über navigator.deviceMemory-API, sofern verfügbar) und reduzieren die Standard-Scale auf mobilen Geräten von 2 auf 1.5. Das halbiert die Pixelmenge und vermeidet Out-of-Memory-Fehler. Für Print-Auflösung müssen mobile Nutzer manuell auf scale 4 hochschalten und ein paar Sekunden Geduld mitbringen.
Was hängenbleibt
Die scale-zu-DPI-Beziehung in pdfjs-dist ist linear: scale 1 ist 72 DPI, scale 4 ist 288 DPI. Die Render-Zeit wächst quadratisch mit der Skalierung. Vor JPG-Export muss der Canvas mit Weiß gefüllt werden, weil JPEG laut ISO/IEC 10918 keinen Alpha-Channel kennt. PNG (RFC 2083) ist verlustfrei und unterstützt Transparenz, kostet aber 3 bis 8 mal mehr Speicherplatz. Standard für Bildschirmdarstellung ist scale 2 (144 DPI), für Print scale 4 (288 DPI). Wer diese Mechanik kennt, kann gezielt zwischen Geschwindigkeit, Größe und Schärfe abwägen.
FAQ
Häufige Fragen
Wie hängen scale-Faktor und DPI zusammen?
PDF nutzt intern 72 Punkte pro Zoll als Basis, was historisch von PostScript stammt. Wenn `pdfjs-dist` mit `getViewport({ scale: 1 })` rendert, entspricht das exakt 72 DPI. Bei scale 2 sind es 144 DPI, bei scale 4 sind es 288 DPI. Die Beziehung ist linear: DPI = 72 × scale. Für gute Lesbarkeit auf Bildschirmen reichen 144 DPI, für Print sollten es 300 DPI sein.
Warum braucht JPG einen weißen Hintergrund?
Das JPEG-Format (`ISO/IEC 10918`, 1992) kennt keinen Alpha-Channel. Transparente Pixel im Canvas werden beim Export zu JPG entweder schwarz oder mit Compression-Artefakten gefüllt, abhängig vom Browser-Renderer. Wir füllen den Canvas vor dem PDF-Rendering mit `fillStyle = 'white'` und `fillRect(0,0,w,h)`, damit transparente Bereiche der PDF-Seite einen sauberen weißen Hintergrund bekommen.
Wann lohnt sich PNG statt JPG?
PNG ist verlustfrei und unterstützt Alpha-Channel. Bei PDFs mit scharfen Kanten (Strichzeichnungen, Tabellen, Text auf farbigem Hintergrund) ist PNG sichtbar besser, weil JPG-Kompression diese Kanten weichzeichnet. Nachteil: Die Datei wird 3 bis 8 mal größer. Für reine Fotos in PDFs ist JPG mit Quality 0.92 fast immer die bessere Wahl, der visuelle Unterschied ist unter normalen Bedingungen nicht zu erkennen.
Welche DPI braucht ein PDF für Druck?
Standard für Print ist 300 DPI, das entspricht scale 4.16 in `pdfjs-dist`. In der Praxis nehmen wir scale 4, was 288 DPI ergibt, weil die 12 DPI Differenz mit bloßem Auge nicht erkennbar sind und der Performance-Gewinn spürbar ist. Für Großformat-Druck (Plakate ab A2) reichen 150 DPI, weil der Betrachtungsabstand größer ist. Unter 150 DPI sieht man Pixel auf jedem Druck.
Warum dauert hohe Auflösung so lange?
Die Pixelmenge wächst quadratisch mit dem scale-Faktor. Eine A4-Seite hat bei scale 1 etwa 595 × 842 Pixel (502.000 Pixel total). Bei scale 4 sind es 2.380 × 3.368 Pixel oder 8.014.000 Pixel, also 16 mal so viel Rechenaufwand. Bei großen PDFs mit vielen Seiten kann scale 4 daher mehrere Sekunden pro Seite kosten. Web Workers verhindern, dass der UI-Thread während dieser Zeit blockiert.
Quellen
Worauf dieser Ratgeber sich stützt
Verwandte Ratgeber