pdf mit mehrere Seiten in ein Image konvertieren

rernanded

Erfahrenes Mitglied
Hallo
der nachfolgende Code funktioniert leidlich gut:
PHP:
$img1 = new Imagick();
$img1->readImage('123.pdf');
$img1->resetIterator();
$img = $img1->appendImages(true);
$img->setImageFormat("png");
header("Content-Type: image/png");
echo $img->getimagesblob();

Problem: Das erstellte .png-Image hat einen grauen Hintergrund, allerdings nur beim Text, bei Bildern nicht.

Der selbe Code etwas anders:

PHP:
$img1 = new Imagick();
$img1->readImage('123.pdf');
$img1->resetIterator();
$img = $img1->appendImages(true);
$img->setImageFormat("png");
$img->writeImage("wow.png");

...

<img src="wow.png" width="600px">

Hier ist die Auflösung nicht zufriedenstellend.

Info:
Im Ausgangs-.pdf ist der Hintergrund komplett weiß.

MONI
 
Hallo Moni,
das hat sich für mich gar nicht so einfach dargestellt, wie zunächst zu erwarten. Ein einfacher Versuch, den Hintergrund zu setzen, funktionierte nämlich nur eingeschränkt, weil das nur auf die erste Seite wirkte:
Code:
header("Content-Type: image/png");
ini_set('display_errors', '1');
error_reporting(E_ALL);
$img1 = new Imagick();
$img1->setBackgroundColor('red');
$img1->readImage($_SERVER['DOCUMENT_ROOT'] . '/pdf/Anschreiben-Brigitte.pdf');
$img1->setImage($img1->mergeImageLayers(imagick::LAYERMETHOD_FLATTEN));
$img1->resetIterator();
$imgOut = $img1->appendImages(true);
$imgOut->setImageFormat("png");
echo $imgOut->getimagesblob();
Ich habe dann viel gesucht und probiert und an Schluss hat nur dieses funktioniert:
Code:
header("Content-Type: image/png");
ini_set('display_errors', '1');
error_reporting(E_ALL);
$img1 = new Imagick();
$img1->readImage($_SERVER['DOCUMENT_ROOT'] . '/pdf/Anschreiben-Brigitte.pdf');
$img2 = new Imagick();
foreach ($img1 as $c => $page) {
    $pg = new Imagick();
    $pg->setBackgroundColor('red');
    $pg->readImage($_SERVER['DOCUMENT_ROOT'] . '/pdf/Anschreiben-Brigitte.pdf[' . $c . ']');
    $pg->setImage($pg->mergeImageLayers(imagick::LAYERMETHOD_FLATTEN));
    $img2->addImage($pg);
}
$img2->resetIterator();
$imgOut = $img2->appendImages(true);
$imgOut->setImageFormat("png");
echo $imgOut->getimagesblob();
Ziemlich umständlich und alles andere als geradlinig aber ich habe keine andere Lösung gefunden.

Beste Grüße, Ulrich
 
Hi sempervivum (Ulrich),
habs probiert und voila: alles gut. Bis auf die Qualität der Schrift, teilweise. Kann ich die Deiner Meinung nach noch mit setCompression und/oder setResolution oder ... verbessern?
Probiert hab ich es schon aber so richtig besser wird es nicht. Vllt. liegt es daran wo genau ich die Codezeilen einsetzen muß?!
MONI
 
Solange es PNG ist, wird setCompression keine Änderung bringen weil PNG verlustfrei komprimiert und keine Einstellung der Stärke möglich ist.

setResolution wird hier diskutiert:
how to get a better resolution with imagemagick and php?
aber nur das "wie" und nicht ob es Erfolg verspricht. Ich erwarte, dass die Auflösung nur einen Einfluss hat, wenn das Ergebnis gedruckt werden soll und nicht bei der Anzeige auf dem Bildschirm.
 
Hier habe ich eine deutliche Qualitäts-Verbesserung (sehr klarer Text), allerdings ohne das am Ende alle pdf-Seiten in einem Bild zusammengefasst sind. Resultat bisher: Nur die letzte pdf-Seite als Bild.
Ich probiere gerade alle Seiten als ein Bild zu erhalten, doch da verlässt mich schon wieder mein Glück.
PHP:
$im = new imagick();
$im->setResolution(300, 300);
$im->readImage('123.pdf');
$im->setImageFormat('jpeg');
$im->setImageCompression(imagick::COMPRESSION_JPEG);
$im->setImageCompressionQuality(100);
$im->writeImage('wow.jpg');
$im->clear();
$im->destroy();

So geht es nicht:
PHP:
$im = new imagick();
$im->setResolution(300, 300);
$im->readImage('123.pdf');
$im->setImageFormat('jpeg');
$im->setImageCompression(imagick::COMPRESSION_JPEG);
$im->setImageCompressionQuality(100);
$im->resetIterator();
$im2 = $im->appendImages(true);
$im2->writeImage('wow.jpg');
$im2->clear();
$im2->destroy();
<img src="wow.jpg" width="600px">

Fatal error: Uncaught ImagickException: width or height exceeds limit `123.pdf'


MONI
 
Zuletzt bearbeitet:
Diese Einstellungen kannst Du problemlos auch auf meine Version anwenden:
Code:
<?php
// header("Content-Type: image/png");
ini_set('display_errors', '1');
error_reporting(E_ALL);
$img1 = new Imagick();
$img1->readImage($_SERVER['DOCUMENT_ROOT'] . '/pdf/Anschreiben-Brigitte.pdf');
$img2 = new Imagick();
foreach ($img1 as $c => $page) {
    $pg = new Imagick();
    $pg->setBackgroundColor('red');
    $pg->readImage($_SERVER['DOCUMENT_ROOT'] . '/pdf/Anschreiben-Brigitte.pdf[' . $c . ']');
    $pg->setImage($pg->mergeImageLayers(imagick::LAYERMETHOD_FLATTEN));
    $img2->addImage($pg);
}
$img2->resetIterator();
$imgOut = $img2->appendImages(true);
$imgOut->setResolution(300, 300);
$imgOut->setImageFormat('jpeg');
$imgOut->setImageCompression(imagick::COMPRESSION_JPEG);
$imgOut->setImageCompressionQuality(100);
$imgOut->writeImage($_SERVER['DOCUMENT_ROOT'] . '/all.jpg');
$imgOut->clear();
$imgOut->destroy();
?>
<img src="all.jpg" width="600px">
Komischer Weise muss ich beim Lesen und Schreiben immer den absoluten Dateinamen angeben, sonst funktioniert es nicht.
 
Hatte ich bereits so probiert. Die Qualität verbessert sich allerdings nicht.
Der Trick muß ein anderer sein. Ev. müssen erst explizit die Einzelseiten konvertiert werden und dann zusammengefügt werden.
Diese vier Zeilen hatte ich auch weiter oben probiert, nach $img1->readImage():
PHP:
->setResolution(300, 300);
->setImageFormat('jpeg');
->setImageCompression(imagick::COMPRESSION_JPEG);
->setImageCompressionQuality(100);
Auch so:
PHP:
->setResolution(300, 300);
->setFormat('jpeg');
->setCompression(imagick::COMPRESSION_JPEG);
->setCompressionQuality(100);

Fehlanzeige.

Problem:
Mein Job ist es eine Präsentation durchzuführen die man auch auf Smartphones problemlos anschauen kann. Dazu werden mir von Kollegen:innen .pdf gemailt (min. 3 - max. 10 Seiten) die ich in Bilder verwandele. Denn: .pdfs sind nicht direkt im Browser von Smartphones anzuschauen. Dazu bedarf es ev. einer APP oder einer Browsererweiterung - zu umständlich wegen der vielen Smartphones wegen Android und IOS und wegen ...

Nun dachte ich alternativ, ich könnte die Einzelseiten der .pdfs in Images umwandeln(das kann ich in guter Qualität) und dann eine Funktion schreiben die sofort die Einzelbilder als Pakete hochlädt um nicht jedes Einzelbild einzeln hochzuladen und einer Person zuzuordnen.

Der Sinn hinter der Erstellung von einem Bild pro Person ist, dass ich besser ein Bild einer Person zuordnen kann, als je nach unterschiedlicher Seitenzahl in den Ursprungs-pdf mal einer Person drei Bilder, einer 10 Bilder und einer weiteren sechs Bilder usw.

Bei ca. 130 Personen besteht dann die Gefahr, dass ich dabei etwas durcheinander komme. Ganz abgesehen vom Arbeitsaufwand.

Gut, ich kann den Bildern folgende Dateinamen geben: sandra-1.jpg, sandra-2.jpg, sandra-3.jpg.
Aber mit einem Bild zum Schluß pro Person ist es echt am simpelsten. Auch für die Wiedergabe im Browser. Portrait = alle Bilder untereinander und Landscape = ev. auch nebeneinander. Problem hier, ich schreibe die entsprechende php-/html-Seite nicht, wo die Bilder eingebettet werden.


MONI
 
Zuletzt bearbeitet:
Guten Morgen Moni!
.pdfs sind nicht direkt im Browser von Smartphones anzuschauen. Dazu bedarf es ev. einer APP oder einer Browsererweiterung - zu umständlich wegen der vielen Smartphones wegen Android und IOS und wegen ...
Das leuchtet ein, gut zu wissen, was der Hintergrund bei der ganzen Sache ist.
Nun dachte ich alternativ, ich könnte die Einzelseiten der .pdfs in Images umwandeln(das kann ich in guter Qualität) und dann eine Funktion schreiben die sofort die Einzelbilder als Pakete hochlädt um nicht jedes Einzelbild einzeln hochzuladen und einer Person zuzuordnen.
...

Bei ca. 130 Personen besteht dann die Gefahr, dass ich dabei etwas durcheinander komme. Ganz abgesehen vom Arbeitsaufwand.
Wäre es eine Option, das PDF auf den Server hochzuladen und das PHP-Skript generiert die Einzelbilder und legt auch gleich das HTML an? Wenn das automatisiert ist, kann nichts durcheinander kommen.
Das hätte auch den Vorteil, dass Du mit der Anordnung der einzelnen Seiten flexibel bist und sie responsiv gestalten kannst.
 
PS: Nachdem ich mir mein eigenes Ausgabebild genau angesehen habe, konnte ich feststellen, dass die Qualität vollkommen lausig ist: Ein eingebettetes Bild ist total verpixelt während die Qualität einwandfrei ist, wenn ich es mir direkt das PDF im Betrachter ansehe.

Mein Code in #7 war ein wenig zu kurz gedacht: Um durchgängig eine hohe Auflösung zu erreichen muss man auf jeder Zwischenstufe die Auflösung setzen:
Code:
<?php
// header("Content-Type: image/png");
ini_set('display_errors', '1');
error_reporting(E_ALL);
$img1 = new Imagick();
$img1->setResolution(300, 300);
$img1->readImage($_SERVER['DOCUMENT_ROOT'] . '/pdf/Anschreiben-Brigitte.pdf');
$img2 = new Imagick();
$img2->setResolution(300, 300);
foreach ($img1 as $c => $page) {
    $pg = new Imagick();
    $pg->setResolution(300, 300);
    $pg->setBackgroundColor('red');
    $pg->readImage($_SERVER['DOCUMENT_ROOT'] . '/pdf/Anschreiben-Brigitte.pdf[' . $c . ']');
    $pg->setImage($pg->mergeImageLayers(imagick::LAYERMETHOD_FLATTEN));
    $img2->addImage($pg);
}
$img2->resetIterator();
$imgOut = new Imagick();
$imgOut->setResolution(300, 300);
$imgOut = $img2->appendImages(true);
$imgOut->setImageFormat('jpeg');
$imgOut->setImageCompression(imagick::COMPRESSION_JPEG);
$imgOut->setImageCompressionQuality(100);
$imgOut->writeImage($_SERVER['DOCUMENT_ROOT'] . '/all-resolution.jpg');
$imgOut->clear();
$imgOut->destroy();
?>
<img src="all-resolution.jpg" width="600px">
Dann ist die Qualität einwandfrei.
 
Zurück