64 lines
1.8 KiB
PHP
64 lines
1.8 KiB
PHP
<?php
|
|
|
|
namespace App\Domains\Unterschrift\Actions\RenderPreview;
|
|
|
|
use Imagick;
|
|
use ImagickPixel;
|
|
use RuntimeException;
|
|
|
|
class RenderPreviewCommand
|
|
{
|
|
/** Aufloesung fuer die Vorschaubilder (klein halten, Platzierung erfolgt relativ). */
|
|
private const PREVIEW_DPI = 96;
|
|
|
|
/** Maximale Seitenzahl, die verarbeitet wird. */
|
|
public const MAX_PAGES = 30;
|
|
|
|
public function __construct(private readonly RenderPreviewRequest $request) {}
|
|
|
|
public function execute(): RenderPreviewResponse
|
|
{
|
|
$doc = new Imagick();
|
|
$doc->setResolution(self::PREVIEW_DPI, self::PREVIEW_DPI);
|
|
|
|
try {
|
|
$doc->readImage($this->request->pdfPath);
|
|
} catch (\ImagickException $e) {
|
|
throw new RuntimeException('Das PDF konnte nicht gelesen werden.', 0, $e);
|
|
}
|
|
|
|
$pageCount = $doc->getNumberImages();
|
|
|
|
if ($pageCount < 1) {
|
|
throw new RuntimeException('Das PDF enthält keine Seiten.');
|
|
}
|
|
|
|
if ($pageCount > self::MAX_PAGES) {
|
|
throw new RuntimeException('Das PDF hat zu viele Seiten (max. ' . self::MAX_PAGES . ').');
|
|
}
|
|
|
|
$pages = [];
|
|
|
|
for ($i = 0; $i < $pageCount; $i++) {
|
|
$doc->setIteratorIndex($i);
|
|
$doc->setImageBackgroundColor(new ImagickPixel('white'));
|
|
|
|
if ($doc->getImageAlphaChannel()) {
|
|
$doc->setImageAlphaChannel(Imagick::ALPHACHANNEL_REMOVE);
|
|
}
|
|
|
|
$doc->setImageFormat('png');
|
|
|
|
$pages[] = [
|
|
'dataUri' => 'data:image/png;base64,' . base64_encode($doc->getImageBlob()),
|
|
'width' => $doc->getImageWidth(),
|
|
'height' => $doc->getImageHeight(),
|
|
];
|
|
}
|
|
|
|
$doc->clear();
|
|
|
|
return new RenderPreviewResponse(pages: $pages, pageCount: $pageCount);
|
|
}
|
|
}
|