Einzelne Seiten aus einer PDF-Datei beim Upload als JPG exportieren / speichern
Viele Kunden wünschen sich ein Download-Archiv. Klassischerweise werden reihenweise PDF-Dateien hochgeladen. Damit das ganze ansprechender aussieht und sich der Besucher der Website vor dem Download im wahrsten Sinne des Wortes ein Bild machen kann, wäre es ja praktisch, einzelne Seiten aus einer PDF als JPG extrahieren zu können. Wir zeigen Theme-Entwicklern wie das unkompliziert ohne zusätzliche Programme direkt beim Upload geschehen kann.
In einem ersten Schritt zeigen wir, wie man innerhalb seines Themes mit Bordmitteln bzw. einer entsprechenden WordPress-Funktion eine JPG-Datei ausgehend von einem PDF-Upload anzeigen lassen kann.
WordPress beherrscht das Extrahieren der ersten Seite einer PDF-Datei bereits von Haus aus. Das ist auch sinnvoll, da man so in der Mediathek immer eine schöne Vorschau-Ansicht erhält. Die Betonung liegt auf der ersten Seite. Möchte man eine andere Seite extrahieren, geschieht dies nicht automatisch.
Folgender Funktion kann im Rahmen des Themes die ID des PDF-Dokumentes (Attachment) übergeben werden. Anschließend gibt die Funktion ein Bild aus. Neben der ID kann zusätzlich die gewünschte Größe angegegeben werden. Wird hier nichts angegeben, wird automatisch thumbnail gewählt. In unserem Beispiel haben wir uns für large entschieden.
$image = wp_get_attachment_image( $attachment_id, 'large' );
Zugegeben. Diese Funktion ist sehr simpel und zügig im Einsatz. Allerdings offenbaren sich bei genauerer Betrachtung verschiedene Schwächen (für den vorgesehenen Einsatz in der WordPress-Mediathek sind diese allerdings weniger gewichtig):
- Wie wähle ich eine andere Seite, z.B. wenn ich nicht nur die erste Seite als JPG darstellen möchte?
- Die Qualität überzeugt nicht sonderlich? Wie kann ich die Qualität verbessern?
- Gibt es noch andere mögliche Ausgabeformate und -größen?
Ein WordPress-Filter sie alle zu retten!
Um nun etwas mehr Einfluss nehmen zu können, schreiben wir uns einen eigenen WordPress-Filter. Dieser greift generell bei Uploads auf die entsprechenden PDF-Dateien und legt immer eine JPG-Datei zusätzlich an. Der Clou: Wir bestimmen selber, welche Seite und Qualität wir uns wünschen.
Dieser Code-Schnippsel gehört in die functions.php-Datei (oder wahlweise in ein eigenes Plugin):
Serverseitige Voraussetzung: Imagemagick
Damit dieser Code funktioniert, muss serverseitig "Imagemagick" installiert und eingerichtet sein. Bei sehr vielen Installationen ist das mittlerweile Standard. Bitte ggf. mal beim Hoster des Vertrauens nachfragen ob diese Erweiterung installiert und einsatzbereit ist.
<?php
add_filter( 'wp_handle_upload', 'pix_pdfextract_upload', 10, 2 );
function pix_pdfextract_upload( $upload, $context ) {
if( $upload['type'] == 'application/pdf' ) {
$imagick = new Imagick();
$imagick->setResolution(300, 300);
$imagick->readImage($upload['file'].'[0]');
$imagick->setImageFormat('jpg');
$imagick->scaleImage(1200, 1200, true);
$imagick->setImageAlphaChannel(Imagick::VIRTUALPIXELMETHOD_WHITE);
$imagick->mergeImageLayers(Imagick::LAYERMETHOD_FLATTEN);
file_put_contents($upload['file'].'.jpg', $imagick);
}
return $upload;
}
Nun wird bei jedem PDF-Upload in die Mediathek automatisch eine Variante als JPG abgespeichert. Der Name entspricht exakt dem der PDF-Datei, nur dass man .jpg dran hängt um das Bild aufzurufen. Heißt die Datei beispielsweise test.pdf, so wird das passende JPG test.pdf.jpg heißen. Dafür sorgt die Funktion file_put_contents()
Und wie kann ich die 2. Seite als JPG abspeichern lassen?
Möchte man nun statt der ersten zum Beispiel die zweite Seite abspeichern lassen, können wir folgende Zeile innerhalb des Filters anpassen:
$imagick->readImage($upload['file'].'[1]');
Vorher war dort statt der 1 eine 0 notiert. Wie bei Arrays üblich startet man mit der Ziffer 0 um die erste Seite anzusprechen. Möchte man also die zweite Seite der PDF-Datei als JPG exportieren, setzt man hier statt der 0 eine 1. Die dritte Seite würde dann…richtig geraten…mit der Ziffer 2 ausgelesen.
Und wie kann ich statt einer JPG- eine PNG-Datei erstellen lassen?
Auf Wunsch kann auch statt einer JPG-Datei ein PNG erstellt werden. Dies ist zum Beispiel sinnvoll wenn man wie im nächsten Schritt beschrieben Transparenz benötigt (das JPG-Format unterstützt keine Transparenz). Folgende Zeile ist anzupassen:
$imagick->setImageFormat('png');
Ich würde statt eines weißen Hintergrundes gerne die Transparenz wahren, geht das?
Möchte man statt eines weißen Hintergrundes lieber die Transparenz der PDF-Datei wahren (um die Datei anschließend als transparentes PNG zu speichern zum Beispiel), ist auch das möglich. Einfach folgende Zeile aus dem Filter entfernen!
/* $imagick->setImageAlphaChannel(Imagick::VIRTUALPIXELMETHOD_WHITE); */
Und kann das Bild individuell skaliert werden?
In unserem Code-Beispiel wird eine JPG-Datei mit einer maximalen Breite und einer maximalen Höhe von 1200 Pixeln erstellt. Für die meisten Anwendungen ist das ausreichend. Hin und Wieder reicht aber auch eine wesentlich kleinere Größe (zudem spart es natürlich wertvollen Plattenspeicher). Die Werte für Höhe und Breite können ebenfalls beliebig verändert werden (im folgenden Beispiel wird eine maximale Höhe und Breite von 300 Pixeln für das Bild festgelegt).
$imagick->scaleImage(300, 300, true);
Probleme beim Upload von PDF-Dateien in die WordPress-Mediathek?
Lädt man eine PDF-Datei hoch, kann es u.U vorkommen, dass WordPress den Upload mit folgendem Fehler quittiert: „Unerwartete Antwort des Servers. Die Datei wurde möglicherweise erfolgreich hochgeladen. Schau in der Mediathek nach oder lade die Seite neu.”
Um die Sicherheit zu erhöhen ist es serverseitig notwendig, Imagemagick explizit über die „policy.xml“-Datei die Erlaubnis zu erteilen PDFs erstellen zu dürfen. Mehr Informationen: https://www.imagemagick.org/script/security-policy.php
Ein möglicher Lösungsweg als Beispiel unter Debian10 sieht folgendermaßen aus:
cd /etc/ImageMagick-6
nano policy.xml
"Auskommentieren" (rausholen) der folgenden Zeile: <!-- <policy domain="coder" rights="none" pattern="PDF" /> -->
service apache2 restart
Fazit: Schnell eingebunden und flexibel einsetzbar
Der Filter ist schnell eingebunden und individuell anpassbar. Der Kunde wird es einem danken, wenn nicht ständig ein Bildbearbeitungsprogramm zu Rate gezogen werden muss um mühsam per Hand Cover-Bilder von PDF-Uploads zu erstellen. Gerade wer mit Gutenberg oder Advanced Custom Fields arbeitet, wird seine wahre Freude an den verschiedenen Einsatzzwecken haben.
Danke Ihre hilfreiche Anzeigen,wir lernen vieles von Ihnen.
Gute Arbeit,nur so weiter!!
Wirklich sehr informativ und hilfreich!
Vielen Dank.
wirklich schnell eingebunden und flexibel einsetzbar.
Gruß, Anna
Danke, so werde ich mir demnächst einiges an Arbeit erleichtern!