PHP Imagick: Bild wird als html gespeichert
Dirk
- html
- php
Moin, ich lese schon einige Zeit mit. Leider kann ich kaum helfen, hier sind so viele Profis, mein Fachwissen reicht da nicht aus. Nun habe ich eine Frage, bei der ich hilflos bin: Ich entwickel für uns ein Tagebuch (html, js, php), ganz klassisch. A uf einer Indexseite werden die Einträge angezeigt die im Adminbereich erstellt werden können. Im Adminbereich kann ich auch Bilder (jpg, png), Dokumente (pdf) und Videos(mp4) hochladen und als Thunbnails verkleinern. Das klappt mit Bildern und Videos sehr gut, nur nicht mit pdf-Dateien. Ich habe ein php-Script, das nimmt sich die erste Seite vom Dokument, skaliert sie und speichert sie als png-Bild.
// PDF: Erste Seite rendern, wenn Imagick vorhanden
if ($extension === 'pdf' && class_exists('Imagick')) {
try {
$site = 0;// erste Seite
$fileName = pathinfo($sourcePath, PATHINFO_FILENAME) .'.png';
$targetPath = $this->thumbDir . $fileName;
$imagick = new Imagick();
$imagick->setResolution(200, 200);
$imagick->readImage($sourcePath .'['. $site .']');
$imagick->setImageFormat('png');
$imagick->thumbnailImage(200, 0);
$imagick->writeImage($targetPath);
$imagick->clear();
$imagick->destroy();
return true;);
} catch (Exception $e) {
$_SESSION['msg'] = 'pdf-Vorschau erstellen fehlgeschlagen: ' . $e;
return false;
}
}
Das Script wird ausgedührt, die Datei wird erstellt ($sourcePath, $targetPath sind ok), kann aber von der Indexseite nicht angezeigt werden. In firefox -> Netzwerkanalyse steht:
test.png -> Initiator: img -> Typ: html (und der muss ja png sein).
Ich habe natürlich schon Einiges gelesen und versucht, komme aber zu keiner Lösung. Vielleicht hat hier jemand eine Idee
und zeigt mir eine Lösungsmöglichkeit.
Gruss Dirk
Moin Dirk,
// PDF: Erste Seite rendern, wenn Imagick vorhanden if ($extension === 'pdf' && class_exists('Imagick')) { try { $site = 0;// erste Seite $fileName = pathinfo($sourcePath, PATHINFO_FILENAME) .'.png'; $targetPath = $this->thumbDir . $fileName; $imagick = new Imagick(); $imagick->setResolution(200, 200); $imagick->readImage($sourcePath .'['. $site .']');
OK, das sollte tatsächlich die erste Seite lesen. (Man könnte es noch schöner schreiben, aber daran wird es nicht scheitern: "$sourcePath[$site]".)
Allerdings prüfst Du nicht den Rückgabewert der Methode hier – ist das wirklich true?
$imagick->setImageFormat('png');
Bei dieser Methode bin ich mir nach Lesen der Dokumentation und der Kommentare nicht sicher, ob der Aufruf überhaupt notwendig ist, weil writeImage den Dateityp aus dem Namen ableitet. Auf jeden Fall werden auch hier nicht die Rückgabewerte überprüft und könnten auf einen Fehler hindeuten.
$imagick->thumbnailImage(200, 0); $imagick->writeImage($targetPath); $imagick->clear(); $imagick->destroy();
destroy wurde durch clear abgelöst und ist unnötig.
return true;); } catch (Exception $e) { $_SESSION['msg'] = 'pdf-Vorschau erstellen fehlgeschlagen: ' . $e; return false; } }Das Script wird ausgedührt, die Datei wird erstellt ($sourcePath, $targetPath sind ok),
Wie hast Du das überprüft?
kann aber von der Indexseite nicht angezeigt werden. In firefox -> Netzwerkanalyse steht:
test.png -> Initiator: img -> Typ: html(und der muss ja png sein).
Was kommt denn beim Browser tatsächlich an? Du kannst Dir in der Netzwerk-Analyse auch den Inhalt anschauen. HTML könnte z.B. auch eine Fehlerseite vom Server sein.
Viele Grüße
Robert
Hallo,
die Frage ist, ob Imagick den Content-Type Header korrekt setzt.
Was kommt denn beim Browser tatsächlich an?
Hier wären vor allem die Header zu überprüfen.
Nur...
Das klappt mit Bildern und Videos sehr gut, nur nicht mit pdf-Dateien. Ich habe ein php-Script, das nimmt sich die erste Seite vom Dokument, skaliert sie und speichert sie als png-Bild.
Was denn jetzt? PDF oder PNG?
Abhängig davon muss der Content-Type application/pdf oder image/png sein. Per Default schickt PHP den Content-Type text/html.
Den Content-Type Header setzt man in PHP so, und zwar bevor der erste Output zum Browser geschickt wurde, sonst kommt die "Headers already sent" Fehlermeldung:
header('Content-Type:application/pdf');
Rolf
Moin Rolf,
Das klappt mit Bildern und Videos sehr gut, nur nicht mit pdf-Dateien. Ich habe ein php-Script, das nimmt sich die erste Seite vom Dokument, skaliert sie und speichert sie als png-Bild.
Was denn jetzt? PDF oder PNG?
Ich generiere u.a. ein kleines png-Vorschaubild aus einer hochgeladenen pdf-Datei um auf meiner Übersichtsseite die Ladezeiten klein zu halten.
Das Problem ist aber gelöst und saß mal wieder vor dem Monitor.
Gruss Dirk
Danke dir Robert, es klappt jetzt!
Vorweg noch: return true;); war ein Übertragungsfehler, im Original return true;
Deine Anmerkungen und Vorschläge werde ich entsprechend auch noch umsetzen. Ich hatte das Script mal woher und bei mir unter Snippets abgelegt und dann jetzt bei mir so verwendet.
Das Script wird ausgedührt, die Datei wird erstellt ($sourcePath, $targetPath sind ok).
Wie hast Du das überprüft?
Mit var_dump() und die Bilder waren am richtigen Ort (original-pdf in /storage/media/ und Vorschau-png in /storage/thumb/), aber...trotz zigmal draufschauen ist mir ein Fehler nicht aufgefallen. Ich speicher die Mediennamen in der DB und sorge dafür, dass sie strtolower() sind. Habe ich aber beim Anlegen der Pfade nicht beachtet🙁, so sollte test-20251126.png die Datei Test-20251126.png aufrufen, was zu einer weissen Seite führte, auch weil diese Fehlermöglich nicht abgefangen wird. Werde ich jetzt aber nachholen.
Also, manchmal hilft es, wenn ein anderer drüberguckt.
Vielen Dank nochmal
Gruss Dirk