19 declare(strict_types=1);
42 protected int $status = self::STATUS_UNKNOWN;
53 $this->image = new \Imagick();
66 $this->status = self::STATUS_FAILED;
67 $this->throwable = $t;
68 if ($this->conversion_options->throwOnError()) {
77 $requested_width = $this->conversion_options->getWidth();
78 $requested_height = $this->conversion_options->getHeight();
79 $original_image_width = $this->image->getImageWidth();
80 $original_image_height = $this->image->getImageHeight();
82 switch ($this->conversion_options->getDimensionMode()) {
88 if ($this->conversion_options->hasCrop()) {
89 $final_height = $requested_height;
90 $final_width = $requested_width;
103 if ($requested_width > 0 && $requested_height > 0) {
104 $final_width = $requested_width;
105 $final_height = $requested_height;
107 throw new \InvalidArgumentException(
'Dimension Mode does not match the given width/height');
112 if ($requested_width ===
null && $requested_height > 0) {
113 $ratio = $original_image_height / $requested_height;
114 $final_width = intval($original_image_width / $ratio);
115 $final_height = $requested_height;
118 throw new \InvalidArgumentException(
'Dimension Mode does not match the given width/height');
123 if ($requested_width > 0 && $requested_height ===
null) {
124 $ratio = $original_image_width / $requested_width;
125 $final_width = $requested_width;
126 $final_height = intval($original_image_height / $ratio);
128 throw new \InvalidArgumentException(
'Dimension Mode does not match the given width/height');
133 if ($requested_width ===
null && $requested_height ===
null) {
134 $final_width = $original_image_width;
135 $final_height = $original_image_height;
137 throw new \InvalidArgumentException(
'Dimension Mode does not match the given width/height');
142 if ($this->conversion_options->hasCrop()) {
158 if ($this->conversion_options->getOutputPath() ===
null) {
159 $this->output_stream = Streams::ofString($this->image->getImageBlob());
161 $this->image->writeImage($this->conversion_options->getOutputPath());
162 $this->output_stream = Streams::ofResource(fopen($this->conversion_options->getOutputPath(),
'rb'));
165 $this->output_stream->rewind();
167 $this->status = self::STATUS_OK;
172 $this->image->setImageResolution(
183 $quality = $this->output_options->getQuality();
188 $this->output_options = $this->output_options->withFormat(strtolower($this->image->getImageFormat()));
193 switch ($this->output_options->getFormat()) {
195 $this->image->setImageFormat(
'webp');
196 $this->image->setImageAlphaChannel(\Imagick::ALPHACHANNEL_REMOVE);
197 $this->image = $this->image->mergeImageLayers(\Imagick::LAYERMETHOD_FLATTEN);
198 if ($quality === 0) {
199 $this->image->setOption(
'webp:lossless',
'false');
201 if ($quality === 100) {
202 $this->image->setOption(
'webp:lossless',
'true');
206 $this->image->setImageFormat(
'jpeg');
207 $this->image->setImageAlphaChannel(\Imagick::ALPHACHANNEL_REMOVE);
208 $this->image = $this->image->mergeImageLayers(\Imagick::LAYERMETHOD_FLATTEN);
209 $this->image->setImageCompression(\Imagick::COMPRESSION_JPEG);
210 $this->image->setImageCompressionQuality($quality);
213 $png_compression_level = round($quality / 100 * 9, 0);
214 if ($this->requested_background !==
null && $this->requested_background !==
'transparent') {
215 $this->image->setImageAlphaChannel(\Imagick::ALPHACHANNEL_REMOVE);
217 $this->image->setImageAlphaChannel(\Imagick::ALPHACHANNEL_ACTIVATE);
219 $this->image->setImageFormat(
'png');
220 $this->image->setOption(
'png:compression-level', (
string) $png_compression_level);
223 $this->image->stripImage();
228 $this->requested_background = $this->conversion_options->getBackgroundColor();
229 if ($this->output_options->getFormat(
231 $this->requested_background =
'#FFFFFF';
233 if ($this->output_options->getFormat(
235 $this->requested_background =
'transparent';
237 if ($this->requested_background !==
null) {
238 $this->image->setBackgroundColor(
new \ImagickPixel($this->requested_background));
244 if ($this->conversion_options->makeTemporaryFiles()) {
245 $this->stream = $this->maybeSafeToTempStream($this->stream);
247 $this->stream->rewind();
248 $this->image->readImageFile($this->stream->detach());
254 return $this->status === self::STATUS_OK;
270 return intval(round($initial * self::RESOLUTION_FACTOR, 0));
273 protected function doCrop(
int $width,
int $height): void
275 $this->image->setGravity(\Imagick::GRAVITY_CENTER);
276 $this->image->cropThumbnailImage(
282 protected function doResize(
int $width,
int $height): void
284 $this->image->resizeImage(
287 \Imagick::FILTER_LANCZOS,
294 $this->image->thumbnailImage(
298 !$this->conversion_options->keepAspectRatio(),
FileStream $output_stream
const DIMENSTION_MODE_RESIZE_TO_FIXED
string $requested_background
doThumbnail(int $width, int $height)
const DIMENSION_MODE_KEEP
while($session_entry=$r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) return null
const DIMENSION_MODE_NONE
doCrop(int $width, int $height)
const DIMENSTION_MODE_RESIZE_BY_HEIGHT
doResize(int $width, int $height)
const DIMENSTION_MODE_RESIZE_BY_WIDTH
factoredResolution(int $initial)
__construct(protected ImageConversionOptions $conversion_options, protected ImageOutputOptions $output_options, protected FileStream $stream)
The base interface for all filesystem streams.