diff --git a/readme.md b/readme.md index b680e6e..ef78866 100644 --- a/readme.md +++ b/readme.md @@ -38,21 +38,21 @@ AVIF is preferred over WEBP in case both upgrades are enabled. # Usage -Order of parameters: +Order of parameters is dependant on the router, the default is: -1. Image file. `string` -2. Dimensions. `string` +1. Dimensions & modifiers. `string` +2. Image file. `string` 3. Format. `string` -## Dimensions +## Dimensions & modifiers -Allowed variants: +### Dimensions: - `100x100` - width and height must be equal or less, resized according to AR. - `x100` - height must be equal or less. - `100x` - width must be equal or less. -Modificators: +### Modifiers: - Cropping: - width: `l` - left, `c` - center, `r` - right. @@ -61,12 +61,14 @@ Modificators: - `ifresize-100x200` - do not resize if the source is smaller. - Force dimensions: - `100x200!` - resize to these dimensions, regardless of AR. +- Quality: + - `-q50` - set custom quality -Formats: +## Format: - The format parameter can be used to switch between image file formats, e.g. `` in `` tag for converting jpegs to WEBP/AVIF. -## Types +# Types Insert the src manually: diff --git a/src/Presenters/ResizePresenter.php b/src/Presenters/ResizePresenter.php index 60b9ea2..31b2c53 100644 --- a/src/Presenters/ResizePresenter.php +++ b/src/Presenters/ResizePresenter.php @@ -43,7 +43,7 @@ public function startup(): void public function actionDefault( string $file, ?string $params = null, - ?string $format = null + ?string $format = null, ): void { try { $image = $this->resizer->process( diff --git a/src/Resizer.php b/src/Resizer.php index 4447907..f4ac11c 100644 --- a/src/Resizer.php +++ b/src/Resizer.php @@ -39,11 +39,11 @@ public function __construct( private readonly OutputFormat $outputFormat, ) { - $this->cacheDir = $config->getTempDir() . $config->getCache(); + $this->cacheDir = $this->config->getTempDir() . $this->config->getCache(); FileSystem::createDir($this->cacheDir); /** @var AbstractImagine $library */ - $library = implode('\\', ['Imagine', $config->getLibrary(), 'Imagine']); + $library = implode('\\', ['Imagine', $this->config->getLibrary(), 'Imagine']); $this->imagine = new $library; } @@ -51,7 +51,7 @@ public function __construct( public function process( string $path, ?string $params, - ?string $format = null + ?string $format = null, ): string { $sourceImagePath = $this->getSourceImagePath($path); @@ -63,7 +63,7 @@ public function process( if (!$this->thumbnailExists($thumbnailPath)) { try { $thumbnail = $this->processImage($sourceImagePath, $geometry); - } catch (RuntimeException $e) { + } catch (RuntimeException) { throw new ImageNotFoundOrReadableException('Unable to open image - wrong permissions, empty or corrupted.'); } @@ -77,7 +77,7 @@ public function process( $thumbnail->interlace(ImageInterface::INTERLACE_LINE); } - $thumbnail->save($thumbnailPath, $this->config->getOptions()); + $thumbnail->save($thumbnailPath, $this->config->getOptions($geometry->getResizerParams()->getQuality())); } return $thumbnailPath; diff --git a/src/ResizerConfig.php b/src/ResizerConfig.php index d82e685..4d74841 100644 --- a/src/ResizerConfig.php +++ b/src/ResizerConfig.php @@ -136,6 +136,7 @@ public function getCompressionPng(): int /** + * @param int<0,100>|null $quality * @return array{ * avif_quality: int<0, 100>, * webp_quality: int<0, 100>, @@ -143,13 +144,22 @@ public function getCompressionPng(): int * png_compression_level: int<0, 9> * } */ - public function getOptions(): array + public function getOptions(?int $quality = null): array { + + if ($quality !== null) { + $qualityPng = (int) round($quality / 10); + + if ($qualityPng > 9) { + $qualityPng = 9; + } + } + return [ - 'avif_quality' => $this->getQualityAvif(), - 'webp_quality' => $this->getQualityWebp(), - 'jpeg_quality' => $this->getQualityJpeg(), - 'png_compression_level' => $this->getCompressionPng(), + 'avif_quality' => $quality ?? $this->getQualityAvif() , + 'webp_quality' => $quality ?? $this->getQualityWebp(), + 'jpeg_quality' => $quality ?? $this->getQualityJpeg(), + 'png_compression_level' => $qualityPng ?? $this->getCompressionPng(), ]; } diff --git a/src/ResizerParams.php b/src/ResizerParams.php index 2e83ef1..a6ac59a 100755 --- a/src/ResizerParams.php +++ b/src/ResizerParams.php @@ -9,7 +9,7 @@ class ResizerParams /** * @param positive-int|null $width * @param positive-int|null $height - * @param positive-int|null $quality + * @param int<0,100>|null $quality */ public function __construct( private readonly bool $ifresize, @@ -74,7 +74,7 @@ public function hasWidth(): bool } - /** @return positive-int|null */ + /** @return int<0,100>|null */ public function getHeight(): ?int { return $this->height; diff --git a/src/ResizerParamsParser.php b/src/ResizerParamsParser.php index d15b695..cf403b7 100755 --- a/src/ResizerParamsParser.php +++ b/src/ResizerParamsParser.php @@ -19,7 +19,7 @@ class ResizerParamsParser (!?) # force dimensions, disregard aspect ratio ([+-]?[0-9]*) # horizontal margin, unused ([+-]?[0-9]*) # vertical margin, unused - (?:-q([1-9][0-9]?|100))? # quality, 1-100 + (?:-q([0-9][0-9]?|100))? # quality, 0-100 )$ ~x'; @@ -72,7 +72,7 @@ public function getParams(): ResizerParams } - /** @return positive-int|null */ + /** @return int|null */ private function parseNumericValueToIntOrNull(string $value): ?int { if (strlen($value) === 0) { @@ -82,11 +82,12 @@ private function parseNumericValueToIntOrNull(string $value): ?int if (is_numeric($value)) { $int = (int) $value; - if ($int > 0) { + if ($int >= 0) { return $int; } } return null; } + } diff --git a/tests/ResizerParamsParserTest.php b/tests/ResizerParamsParserTest.php index a010ef4..73ee70e 100644 --- a/tests/ResizerParamsParserTest.php +++ b/tests/ResizerParamsParserTest.php @@ -278,6 +278,44 @@ public function testQuality2(): void } + public function testQuality3(): void + { + $expected = new ResizerParams( + false, + null, + null, + false, + null, + null, + 100, + 200, + 0, + ); + + $actual = $this->parse('100x200-q0'); + $this->assertEquals($expected, $actual); + } + + + public function testQuality4(): void + { + $expected = new ResizerParams( + false, + null, + null, + false, + null, + null, + 100, + 200, + 100, + ); + + $actual = $this->parse('100x200-q100'); + $this->assertEquals($expected, $actual); + } + + public function testWrongKeyword1(): void { $this->expectException(CouldNotParseResizerParamsException::class);