Archiv für den Monat: Juli 2017

Pdf-Dateien in Bitmaps zerlegen mit freier Software

In diesem Beitrag geht es um eine grundsätzlich einfache Anforderung: Ein Pdf-Dokument soll als Teil einer WPF-Anwendung seitenweise als Bitmap-Datei gespeichert werden, so dass sich z.B. eine einfache Seitenvorschau umsetzen lässt.

Natürlich gibt es jede Menge kommerzieller Komponenten, die alle sehr gut sind (ich verwende für ein Projekt z.B. Apose.Pdf for .Net, die ich empfehlen kann, auch wenn sie nicht ganz preiswert ist), und mit deren Hilfe sich die Anforderung in ein paar Zeilen Code umsetzen ließe. Für einen MVVM-Lehrgang ging es mir darum, keine kommerzielle Komponente verwenden zu müssen. Die Suche erwies sich als schwieriger als gedacht, denn die Anzahl freier Pdf-Tools ist mehr als überschaubar. Geht es um das Erstellen von Pdf-Dokumenten sind PdfSharp bzw. Migradoc eine sehr gute Wahl, allerdings bieten sie keine Renedering-Funktionalität.

Die offenbar einzige (!) freie Software, die Pdf-Dateien darstellen kann, ist muPdf von den Ghostscript-Entwicklern Artifex (https://mupdf.com). Der Sourcecode liegt in C vor, die Make-Datei erzeugt offenbar eine Exe-Datei, so dass das Einbinden in eine .NET-Assembly und Aufrufe per p/Invoke keine Option sind.

Zum Glück gibt es immer fleißige Entwickler, die solche Herausforderungen annehmen und anderen das Ergebnis ihrer Arbeit zur Verfügung stellen. Auf Codeproject gibt es zwei Projekte, die eine gute Grundlage für eigene Projekte sind:

1) https://www.codeproject.com/articles/498317/rendering-pdf-documents-with-mupdf-and-p-invoke-in

2) https://www.codeproject.com/Articles/579878/MoonPdfPanel-A-WPF-based-PDF-Viewer-Control

Im ersten Artikel beschreibt der Autor ausführlich, wie er in die von den Entwicklern von SumatraPdf, einem kleinen und feinen Open Source-Pdf-Betrachter, zur Verfügung gestellte muPdf-Bibliothek per p/Invoke einbindet.

Der zweite Artikel verwendet ebenfalls muPdf und macht daraus gleich ein Wpf-Control, das die Seiten eines Pdf-Dokuments anzeigen kann. Einfacher geht es fast nicht mehr.

Ich habe für mein Projekt eine andere Alternative verwendet in Gestalt des enorm vielseitigen Tools ImageMagick (z.B. http://imagemagick.sourceforge.net/http/www/windows.html).

Dieses Tool basiert auf Ghostscript, das daher zuvor installiert werden muss, und liegt als Exe-Datei vor. Es wandelt die Seiten einer Pdf-Datei in Bitmaps in einem beliebigen Format um. Auch wenn es grundsätzlich kein Problem mehr, die Exe-Datei als externen Prozess zu starten, etwas eleganter geht es mit Hilfe von Magick.Net, eine Assembly, die ImageMagick kapselt: https://magick.codeplex.com. Die Assembly kann auch per NuGet hinzugefügt werden. Auch hier muss Ghostscript zuvor installiert werden.

Das Abspeichern der Seiten einer Pdf-Datei als Bitmaps wird damit sehr einfach:

Ob sich diese Lösung auch für „echte“ Projekte eignet, bei denen sehr große Pdf-Dokumente geladen werden sollen, kann ich aktuell nicht beurteilen. Auf der seinen Seite wirkte mein Beispielprogramm etwas langsam und brach einem Versuch eine Pdf-Datei mit 420 Seiten zu laden mit einer OutOfMemoryExcception ab (allerdings hatte ich den Dpi-Wert auch auf 300 eingestellt, so dass jede einzelne Bitmap über 1 MB groß war). Kleinere Dateien mit ca. 40 Seiten werden schnell geladen. Auf der anderen Seite dürften die Entwickler von SumatraPdf dafür sorgen, dass die muPdf-Bibliothek performant genug ist, um auch mit großen Pdf-Dateien klarzukommen (das Laden der 420-Seiten-Datei in Sumatra Pdf ist kein Problem, sie wird praktisch verzögerungsfrei geladen).

Das Hauptausschlußkriterium für die Verwendung von muPdf und Ghostscript in einem Kundenprojekt dürfte das Lizenzmodell sein. Artifex beschreibt es ausführlich unter der folgenden Adresse: http://artifex.com/licensing/. Da es auf AGPL basiert (GNU Affero General Public License), müssste der Sourcecode der eigenen Anwendung veröffentlicht werden, was in der Regel nicht in Frage kommt. In den Lizenzbedingungen wird aber auch darauf hingewiesen, dass unter bestimmten Bedingungen auch eine Exe-Datei ausgeliefert werden darf. Wichtig ist, dass der Anwender erkennt, dass er oder sie muPdf und Ghostscript separat installieren.

Da ich alles andere als ein Experte für Lizenzierungsdetails bin und bei meinem Beispielen ohnehin immer der Quellcode dabei ist, ist dieser Aspekt für mich kein Thema. Für die meisten Entwickler dürfte das Lizenzmodell aber zu restriktiv bzw. „undurchsichtig“ sein (man kann natürlich bei Artifex nachfragen), so dass es am Ende wieder auf eine kommerzielle Komponente hinausläuft. Schade, dass Microsoft dieses Thema komplett ignoriert hat. Ein Pdf-Viewer als Teil des .NET Framework wäre eine natürlich sehr praktisch. Doch aller Voraussicht nach wird es dazu nie kommen.