From ff05f70dcf8ed392535d710f9d6a5a6df6035d67 Mon Sep 17 00:00:00 2001 From: Jon Uhlmann Date: Sun, 28 Jan 2024 22:39:15 +0100 Subject: [PATCH] FEATURE: Add quality option --- Classes/Domain/AbstractImageSource.php | 23 +++++++++++++++++++ Classes/Domain/AssetImageSource.php | 4 ++-- Classes/Domain/ImageSourceInterface.php | 2 ++ .../EelHelpers/ImageSourceHelperInterface.php | 5 ++++ .../AbstractImageSourceImplementation.php | 12 ++++++++++ README.md | 7 ++++++ .../Fusion/Prototypes/AssetImageSource.fusion | 1 + .../Private/Fusion/Prototypes/Image.fusion | 2 ++ .../Private/Fusion/Prototypes/Picture.fusion | 4 ++++ .../Private/Fusion/Prototypes/Source.fusion | 3 +++ 10 files changed, 61 insertions(+), 2 deletions(-) diff --git a/Classes/Domain/AbstractImageSource.php b/Classes/Domain/AbstractImageSource.php index 81d2b36..68c753a 100644 --- a/Classes/Domain/AbstractImageSource.php +++ b/Classes/Domain/AbstractImageSource.php @@ -26,6 +26,11 @@ abstract class AbstractImageSource implements ImageSourceInterface, ProtectedCon */ protected $targetHeight; + /** + * @var int|null + */ + protected $targetQuality; + /** * @var string|null */ @@ -105,6 +110,22 @@ public function withHeight(int $targetHeight, bool $preserveAspect = false): Ima return $newSource; } + /** + * @deprecated + */ + public function setQuality(int $quality): ImageSourceInterface + { + return $this->withQuality($quality); + } + + public function withQuality(int $quality): ImageSourceInterface + { + $newSource = clone $this; + $newSource->targetQuality = $quality; + + return $newSource; + } + /** * @deprecated */ @@ -302,6 +323,7 @@ public function allowsCallOfMethod($methodName) 'withTitle', 'withDimensions', 'withFormat', + 'withQuality', 'withWidth', 'withHeight', 'withThumbnailPreset', @@ -311,6 +333,7 @@ public function allowsCallOfMethod($methodName) 'setHeight', 'setDimensions', 'setFormat', + 'setQuality', 'applyPreset', 'applyThumbnailPreset', 'useVariantPreset', diff --git a/Classes/Domain/AssetImageSource.php b/Classes/Domain/AssetImageSource.php index 8aa9335..0015039 100644 --- a/Classes/Domain/AssetImageSource.php +++ b/Classes/Domain/AssetImageSource.php @@ -137,7 +137,7 @@ public function src(): string $allowCropping, $allowUpScaling, $async, - null, + $this->targetQuality, $this->targetFormat ); @@ -177,7 +177,7 @@ public function dataSrc(): string $allowCropping, $allowUpScaling, $async, - null, + $this->targetQuality, $this->targetFormat ); diff --git a/Classes/Domain/ImageSourceInterface.php b/Classes/Domain/ImageSourceInterface.php index 9a8c45d..9a2c4f3 100644 --- a/Classes/Domain/ImageSourceInterface.php +++ b/Classes/Domain/ImageSourceInterface.php @@ -19,6 +19,8 @@ public function withWidth(int $targetWidth, bool $preserveAspect = false): Image public function withHeight(int $targetHeight, bool $preserveAspect = false): ImageSourceInterface; + public function withQuality(int $targetQuality): ImageSourceInterface; + public function withThumbnailPreset(string $format): ImageSourceInterface; public function withVariantPreset(string $presetIdentifier, string $presetVariantName): ImageSourceInterface; diff --git a/Classes/EelHelpers/ImageSourceHelperInterface.php b/Classes/EelHelpers/ImageSourceHelperInterface.php index 92162b9..acc23ed 100644 --- a/Classes/EelHelpers/ImageSourceHelperInterface.php +++ b/Classes/EelHelpers/ImageSourceHelperInterface.php @@ -28,6 +28,11 @@ public function setHeight(int $height, bool $preserveAspect = false): ImageSourc */ public function setDimensions(int $width, int $height): ImageSourceInterface; + /** + * @deprecated use withQuality + */ + public function setQuality(int $quality): ImageSourceInterface; + /** * @deprecated use withFormat */ diff --git a/Classes/FusionObjects/AbstractImageSourceImplementation.php b/Classes/FusionObjects/AbstractImageSourceImplementation.php index 567b9f1..d19c882 100644 --- a/Classes/FusionObjects/AbstractImageSourceImplementation.php +++ b/Classes/FusionObjects/AbstractImageSourceImplementation.php @@ -25,6 +25,14 @@ public function getHeight(): ?int return $this->fusionValue('height'); } + /** + * @return int|null + */ + public function getQuality(): ?int + { + return $this->fusionValue('quality'); + } + /** * @return string|null */ @@ -94,6 +102,10 @@ public function evaluate(): ?ImageSourceInterface $helper = $helper->withHeight($height); } + if ($quality = $this->getQuality()) { + $helper = $helper->withQuality($quality); + } + if ($format = $this->getFormat()) { $helper = $helper->withFormat($format); } diff --git a/README.md b/README.md index 4c1e3ff..812d584 100644 --- a/README.md +++ b/README.md @@ -88,6 +88,7 @@ Props: - `sizes`: sizes attribute of the default image (string ot array) - `loading`: (optional, default "lazy") loading attribute for the img tag - `format`: (optional) the image-format like `webp` or `png`, will be applied to the `imageSource` +- `quality`: (optional) the image quality from 0 to 100, will be applied to the `imageSource` - `width`: (optional) the base width, will be applied to the `imageSource` - `height`: (optional) the base height, will be applied to the `imageSource` - `alt`: alt-attribute for the img tag (default "") @@ -136,11 +137,13 @@ Props: - `media`: (optional) the media attribute for this source - `type`: (optional) the type attribute for this source - `format`: (optional) the image-format for the source like `webp` or `png`, is applied to `imageSource` and `type` + - `quality`: (optional) the image quality from 0 to 100, will be applied to the `imageSource` - `width`: (optional) the base width, will be applied to the `imageSource` - `height`: (optional) the base height, will be applied to the `imageSource` - `srcset`: media descriptors like '1.5x' or '600w' of the default image (string ot array) - `sizes`: sizes attribute of the default image (string ot array) - `formats`: (optional) image formats that will be rendered as sources of separate type (string or array) +- `quality`: (optional) the image quality from 0 to 100, will be applied to the `imageSource` - `width`: (optional) the base width, will be applied to the `imageSource` - `height`: (optional) the base height, will be applied to the `imageSource` - `loading`: (optional, default "lazy") loading attribute for the img tag @@ -212,6 +215,7 @@ Props: - `srcset`: media descriptors like '1.5x' or '600w' of the default image (string ot array, inherited from picture) - `sizes`: (optional) sizes attribute (string or array, inherited from picture) - `format`: (optional) the image-format like `webp` or `png`, will be applied to `imageSource` and `type` +- `quality`: (optional) the image quality from 0 to 100, will be applied to the `imageSource` - `width`: (optional) the base width, will be applied to the `imageSource` - `height`: (optional) the base height, will be applied to the `imageSource` - `type`: (optional) the type attribute for the source like `image/png` or `image/webp`, the actual format is enforced via `imageSource.withFormat()` @@ -307,6 +311,7 @@ Arguments: - `thumbnailPreset`: `width` and `height` are supported as explained above - `variantPreset`: as explained above - `format`: Set the image output format, like webp (default null) +- `quality`: Set the image quality from 0 to 100 (default null) - `alt`: The alt attribute if not specified otherwise (default null) - `title`: The title attribute if not specified otherwise (default null) @@ -355,6 +360,7 @@ Methods of ImageSource-Helpers that are accessible via Eel: - `withThumbnailPreset( string )`: Set width and/or height via named thumbnail preset from Settings `Neos.Media.thumbnailPresets` - `withVariantPreset( string, string )`: Select image variant via the named variant preset (parameters are "preset identifier" key and "preset variant name" key from Settings `Neos.Media.variantPresets`) - `withFormat( string )`: Set the image format to generate like `webp`, `png` or `jpeg` +- `withQuality( integer )`: Set the image quality from 0 to 100 - `withAlt( ?string )`: Set the alt atttribute for the image tag - `withTitle( ?string )`: Set the title atttribute for the image tag @@ -373,6 +379,7 @@ deprecated methods: - `setHeight( integer $height, bool $preserveAspect = false )`: Set the intended height - `setDimensions( integer, interger)`: Set the intended width and height - `setFormat( string )`: Set the image format to generate like `webp`, `png` or `jpeg` +- `setQuality( integer )`: Set the image quality from 0 to 100 Note: The Eel-helpers cannot be created directly. They have to be created by using the `Sitegeist.Kaleidoscope:AssetImageSource` or diff --git a/Resources/Private/Fusion/Prototypes/AssetImageSource.fusion b/Resources/Private/Fusion/Prototypes/AssetImageSource.fusion index a27ab3b..3bdfa47 100644 --- a/Resources/Private/Fusion/Prototypes/AssetImageSource.fusion +++ b/Resources/Private/Fusion/Prototypes/AssetImageSource.fusion @@ -8,4 +8,5 @@ prototype(Sitegeist.Kaleidoscope:AssetImageSource) { width = null height = null format = null + quality = null } diff --git a/Resources/Private/Fusion/Prototypes/Image.fusion b/Resources/Private/Fusion/Prototypes/Image.fusion index 76f5a48..b9ca0b6 100644 --- a/Resources/Private/Fusion/Prototypes/Image.fusion +++ b/Resources/Private/Fusion/Prototypes/Image.fusion @@ -124,6 +124,7 @@ prototype(Sitegeist.Kaleidoscope:Image) < prototype(Neos.Fusion:Component) { width = null height = null format = null + quality = null attributes = Neos.Fusion:DataStructure renderDimensionAttributes = true @@ -136,6 +137,7 @@ prototype(Sitegeist.Kaleidoscope:Image) < prototype(Neos.Fusion:Component) { imageSource.@process.applyWidth = ${props.width ? value.withWidth(props.width) : value} imageSource.@process.applyHeight = ${props.height ? value.withHeight(props.height) : value} imageSource.@process.applyFormat = ${props.format ? value.withFormat(props.format) : value} + imageSource.@process.applyQuality = ${props.quality ? value.withQuality(props.quality) : value} srcset = ${props.srcset} sizes = ${props.sizes} diff --git a/Resources/Private/Fusion/Prototypes/Picture.fusion b/Resources/Private/Fusion/Prototypes/Picture.fusion index e62892e..43fb779 100644 --- a/Resources/Private/Fusion/Prototypes/Picture.fusion +++ b/Resources/Private/Fusion/Prototypes/Picture.fusion @@ -54,6 +54,7 @@ prototype(Sitegeist.Kaleidoscope:Picture) < prototype(Neos.Fusion:Component) { loading = 'lazy' sources = null formats = null + quality = null width = null height = null alt = '' @@ -76,6 +77,7 @@ prototype(Sitegeist.Kaleidoscope:Picture) < prototype(Neos.Fusion:Component) { __width = ${this.width} __height = ${this.height} __format = ${this.format} + __quality = ${this.quality} } renderer = Neos.Fusion:Component { @@ -86,6 +88,7 @@ prototype(Sitegeist.Kaleidoscope:Picture) < prototype(Neos.Fusion:Component) { imageSource.@process.applyWidth = ${props.width ? value.setWidth(props.width) : value} imageSource.@process.applyHeight = ${props.height ? value.setHeight(props.height) : value} imageSource.@process.applyFormat = ${props.format ? value.setFormat(props.format) : value} + imageSource.@process.applyQuality = ${props.quality ? value.setQuality(props.quality) : value} srcset = ${props.srcset} sizes = ${props.sizes} @@ -111,6 +114,7 @@ prototype(Sitegeist.Kaleidoscope:Picture) < prototype(Neos.Fusion:Component) { format={source.format} width={source.width} height={source.height} + quality={source.quality} srcset={source.srcset ? source.srcset : props.srcset} sizes={source.sizes ? source.sizes : props.sizes} renderDimensionAttributes={props.renderDimensionAttributes} diff --git a/Resources/Private/Fusion/Prototypes/Source.fusion b/Resources/Private/Fusion/Prototypes/Source.fusion index 3939ed7..abf914f 100644 --- a/Resources/Private/Fusion/Prototypes/Source.fusion +++ b/Resources/Private/Fusion/Prototypes/Source.fusion @@ -10,6 +10,7 @@ prototype(Sitegeist.Kaleidoscope:Source) < prototype(Neos.Fusion:Component) { width = null height = null format = null + quality = null type = null media = null renderDimensionAttributes = true @@ -19,6 +20,7 @@ prototype(Sitegeist.Kaleidoscope:Source) < prototype(Neos.Fusion:Component) { @context { imageSource = ${props.imageSource || __imageSource} format = ${props.format || __format} + quality = ${props.quality || __quality} width = ${props.width || __width} height = ${props.height || __height} srcset = ${props.srcset || __srcset} @@ -32,6 +34,7 @@ prototype(Sitegeist.Kaleidoscope:Source) < prototype(Neos.Fusion:Component) { imageSource.@process.applyWidth = ${width ? value.withWidth(width) : value} imageSource.@process.applyHeight = ${height ? value.withHeight(height) : value} imageSource.@process.applyFormat = ${format ? value.withFormat(format) : value} + imageSource.@process.applyQuality = ${quality ? value.withQuality(quality) : value} type = ${format ? 'image/' + format : props.type} srcset = ${srcset}