Files
nexus/app/Domains/Unterschrift/Actions/RenderPreview/RenderPreviewCommand.php
T
2026-07-21 14:35:34 +02:00

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);
}
}