From 6349e1b0270f8299049753701a407fd6b7562111 Mon Sep 17 00:00:00 2001 From: Bas van Dinther Date: Mon, 26 Sep 2022 11:42:29 +0200 Subject: [PATCH 01/13] =?UTF-8?q?Add=20Overlay=20transformation=20?= =?UTF-8?q?=E2=80=98skeleton=E2=80=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Transformations.php | 48 ++++++++++----- src/Transformations/Overlay.php | 58 +++++++++++++++++++ src/Transformations/TransformationsFinder.php | 2 + 3 files changed, 94 insertions(+), 14 deletions(-) create mode 100644 src/Transformations/Overlay.php diff --git a/src/Transformations.php b/src/Transformations.php index ee2dbaf..bd91888 100644 --- a/src/Transformations.php +++ b/src/Transformations.php @@ -2,33 +2,34 @@ namespace Vormkracht10\UploadcareTransformations; -use Vormkracht10\UploadcareTransformations\Transformations\AutoRotate; -use Vormkracht10\UploadcareTransformations\Transformations\BasicColorAdjustments; use Vormkracht10\UploadcareTransformations\Transformations\Blur; -use Vormkracht10\UploadcareTransformations\Transformations\BlurFaces; -use Vormkracht10\UploadcareTransformations\Transformations\BlurRegion; -use Vormkracht10\UploadcareTransformations\Transformations\ConvertToSRGB; use Vormkracht10\UploadcareTransformations\Transformations\Crop; -use Vormkracht10\UploadcareTransformations\Transformations\CropByObjects; -use Vormkracht10\UploadcareTransformations\Transformations\CropByRatio; -use Vormkracht10\UploadcareTransformations\Transformations\Enhance; -use Vormkracht10\UploadcareTransformations\Transformations\Filter; use Vormkracht10\UploadcareTransformations\Transformations\Flip; +use Vormkracht10\UploadcareTransformations\Transformations\Filter; use Vormkracht10\UploadcareTransformations\Transformations\Format; -use Vormkracht10\UploadcareTransformations\Transformations\Grayscale; -use Vormkracht10\UploadcareTransformations\Transformations\ICCProfileSizeThreshold; use Vormkracht10\UploadcareTransformations\Transformations\Invert; use Vormkracht10\UploadcareTransformations\Transformations\Mirror; -use Vormkracht10\UploadcareTransformations\Transformations\Progressive; -use Vormkracht10\UploadcareTransformations\Transformations\Quality; use Vormkracht10\UploadcareTransformations\Transformations\Resize; use Vormkracht10\UploadcareTransformations\Transformations\Rotate; -use Vormkracht10\UploadcareTransformations\Transformations\ScaleCrop; +use Vormkracht10\UploadcareTransformations\Transformations\Enhance; +use Vormkracht10\UploadcareTransformations\Transformations\Overlay; +use Vormkracht10\UploadcareTransformations\Transformations\Quality; use Vormkracht10\UploadcareTransformations\Transformations\SetFill; use Vormkracht10\UploadcareTransformations\Transformations\Sharpen; +use Vormkracht10\UploadcareTransformations\Transformations\BlurFaces; +use Vormkracht10\UploadcareTransformations\Transformations\Grayscale; +use Vormkracht10\UploadcareTransformations\Transformations\ScaleCrop; use Vormkracht10\UploadcareTransformations\Transformations\SmartCrop; +use Vormkracht10\UploadcareTransformations\Transformations\AutoRotate; +use Vormkracht10\UploadcareTransformations\Transformations\BlurRegion; +use Vormkracht10\UploadcareTransformations\Transformations\CropByRatio; +use Vormkracht10\UploadcareTransformations\Transformations\Progressive; use Vormkracht10\UploadcareTransformations\Transformations\SmartResize; use Vormkracht10\UploadcareTransformations\Transformations\ZoomObjects; +use Vormkracht10\UploadcareTransformations\Transformations\ConvertToSRGB; +use Vormkracht10\UploadcareTransformations\Transformations\CropByObjects; +use Vormkracht10\UploadcareTransformations\Transformations\BasicColorAdjustments; +use Vormkracht10\UploadcareTransformations\Transformations\ICCProfileSizeThreshold; class Transformations { @@ -425,4 +426,23 @@ public function mirror(): self return $this; } + + /** + * Adds an image overlay to the original image. + * + * @param string $uuid + * @param int|string $width, + * @param int|string $height, + * @param int|string $coordinateX, + * @param int|string $coordinateY, + * @param int $opacity + * + * @return self + */ + public function overlay(string $uuid, int|string $width, int|string $height, int|string $coordinateX, int|string $coordinateY, int $opacity): self + { + $this->transformations['overlay'] = Overlay::transform($uuid, $width, $height, $coordinateX, $coordinateY, $opacity); + + return $this; + } } diff --git a/src/Transformations/Overlay.php b/src/Transformations/Overlay.php new file mode 100644 index 0000000..80390e5 --- /dev/null +++ b/src/Transformations/Overlay.php @@ -0,0 +1,58 @@ + $uuid, + self::WIDTH => $width, + self::HEIGHT => $height, + self::COORDINATE_X => $coordinateX, + self::COORDINATE_Y => $coordinateY, + self::OPACITY => $opacity, + ]; + } + + public static function validate(string $key, ...$args): ?bool + { + return null; + } + + public static function generateUrl(string $url, array $values): string + { + // Every overlay parameter is optional and can be omitted. However, the order of parameter URL directives should be preserved. + + // -/overlay/:uuid/:relative_dimensions/:relative_coordinates/:opacity/ + + // Check if only UUID is passed + + // Check if only UUID and width/height is passed + + // Check if only UUID and width/height and coordinateX is passed + + // Check if only UUID and width/height and coordinates is passed + + // Check if only UUID and width/height and coordinates and opacity is passed + + return $url; + } +} diff --git a/src/Transformations/TransformationsFinder.php b/src/Transformations/TransformationsFinder.php index 11e18a0..8d00cad 100644 --- a/src/Transformations/TransformationsFinder.php +++ b/src/Transformations/TransformationsFinder.php @@ -21,6 +21,7 @@ class TransformationsFinder public const ICC_PROFILE_SIZE_THRESHOLD = 'icc_profile_size_threshold'; public const INVERT = 'invert'; public const MIRROR = 'mirror'; + public const OVERLAY = 'overlay'; public const PREVIEW = 'preview'; public const PROGRESSIVE = 'progressive'; public const QUALITY = 'quality'; @@ -53,6 +54,7 @@ public static function getTransformation($key) self::ICC_PROFILE_SIZE_THRESHOLD => ICCProfileSizeThreshold::class, self::INVERT => Invert::class, self::MIRROR => Mirror::class, + self::OVERLAY => Overlay::class, self::PREVIEW => Preview::class, self::PROGRESSIVE => Progressive::class, self::QUALITY => Quality::class, From 592073ed6c54e6d74c0b3a6097d38e603e94f5c3 Mon Sep 17 00:00:00 2001 From: Bas van Dinther Date: Fri, 30 Sep 2022 16:07:49 +0200 Subject: [PATCH 02/13] Return format value instead of enum --- src/Transformations/Format.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Transformations/Format.php b/src/Transformations/Format.php index e1f4b76..0d6de6b 100644 --- a/src/Transformations/Format.php +++ b/src/Transformations/Format.php @@ -11,7 +11,7 @@ class Format implements TransformationInterface public static function transform(...$args): array { - $format = FormatEnum::tryFrom($args[0]); + $format = FormatEnum::tryFrom($args[0])->value; if (! $format) { throw new \InvalidArgumentException('Invalid format'); From 740294d056ca8c708ba8d0c472726b8478c8b505 Mon Sep 17 00:00:00 2001 From: Bas van Dinther Date: Fri, 30 Sep 2022 16:09:28 +0200 Subject: [PATCH 03/13] Fix unreachable code error --- src/Transformations/Format.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Transformations/Format.php b/src/Transformations/Format.php index 0d6de6b..17a7c65 100644 --- a/src/Transformations/Format.php +++ b/src/Transformations/Format.php @@ -11,9 +11,9 @@ class Format implements TransformationInterface public static function transform(...$args): array { - $format = FormatEnum::tryFrom($args[0])->value; + $format = $args[0]; - if (! $format) { + if (! FormatEnum::tryFrom($format)) { throw new \InvalidArgumentException('Invalid format'); } From 52aa85fc8cc6884aaaef45ce2a6f32b34f5affb0 Mon Sep 17 00:00:00 2001 From: Bas van Dinther Date: Fri, 30 Sep 2022 16:15:05 +0200 Subject: [PATCH 04/13] Overlay (wip) --- src/Transformations.php | 18 ++++++++++----- src/Transformations/Overlay.php | 41 +++++++++++++++++++++++++++------ 2 files changed, 46 insertions(+), 13 deletions(-) diff --git a/src/Transformations.php b/src/Transformations.php index bd91888..455ce6b 100644 --- a/src/Transformations.php +++ b/src/Transformations.php @@ -431,15 +431,21 @@ public function mirror(): self * Adds an image overlay to the original image. * * @param string $uuid - * @param int|string $width, - * @param int|string $height, - * @param int|string $coordinateX, - * @param int|string $coordinateY, - * @param int $opacity + * @param int|string|null $width, + * @param int|string|null $height, + * @param int|string|null $coordinateX, + * @param int|string|null $coordinateY, + * @param int|null $opacity * * @return self */ - public function overlay(string $uuid, int|string $width, int|string $height, int|string $coordinateX, int|string $coordinateY, int $opacity): self + public function overlay( + string $uuid, + int|string|null $width = null, + int|string|null $height = null, + int|string|null $coordinateX = null, + int|string|null $coordinateY = null, + int|null $opacity = null): self { $this->transformations['overlay'] = Overlay::transform($uuid, $width, $height, $coordinateX, $coordinateY, $opacity); diff --git a/src/Transformations/Overlay.php b/src/Transformations/Overlay.php index 80390e5..cdc924a 100644 --- a/src/Transformations/Overlay.php +++ b/src/Transformations/Overlay.php @@ -34,24 +34,51 @@ public static function transform(...$args): array public static function validate(string $key, ...$args): ?bool { + /** @todo add validation */ return null; } public static function generateUrl(string $url, array $values): string { // Every overlay parameter is optional and can be omitted. However, the order of parameter URL directives should be preserved. - // -/overlay/:uuid/:relative_dimensions/:relative_coordinates/:opacity/ - // Check if only UUID is passed - - // Check if only UUID and width/height is passed + // Check if only uuid is set + /** @todo add UUID checks */ + // if (isset($values[self::UUID]) ) + + // Check if only width/height is passed. + if (isset($values[self::WIDTH]) && + isset($values[self::HEIGHT]) && + !isset($values[self::COORDINATE_X]) && + !isset($values[self::COORDINATE_Y])) { + return $url . '-/overlay/' . $values[self::WIDTH] . 'x' . $values[self::HEIGHT] . '/'; + } - // Check if only UUID and width/height and coordinateX is passed + // Check if only width/height and coordinateX is passed. + if (isset($values[self::WIDTH]) && + isset($values[self::HEIGHT]) && + isset($values[self::COORDINATE_X]) && + !isset($values[self::COORDINATE_Y])) { + return $url . '-/overlay/' . $values[self::WIDTH] . 'x' . $values[self::HEIGHT] . '/' . $values[self::COORDINATE_X] . '/'; + } - // Check if only UUID and width/height and coordinates is passed + // Check if only width/height and coordinates is passed. + if (isset($values[self::WIDTH]) && + isset($values[self::HEIGHT]) && + isset($values[self::COORDINATE_X]) && + isset($values[self::COORDINATE_Y])) { + return $url . '-/overlay/' . $values[self::WIDTH] . 'x' . $values[self::HEIGHT] . '/' . $values[self::COORDINATE_X] . 'x' . $values[self::COORDINATE_Y] . '/'; + } - // Check if only UUID and width/height and coordinates and opacity is passed + // Check if only width/height and coordinates and opacity is passed. + if (isset($values[self::WIDTH]) && + isset($values[self::HEIGHT]) && + isset($values[self::COORDINATE_X]) && + isset($values[self::COORDINATE_Y]) && + isset($values[self::OPACITY])) { + return $url . '-/overlay/' . $values[self::WIDTH] . 'x' . $values[self::HEIGHT] . '/' . $values[self::COORDINATE_X] . 'x' . $values[self::COORDINATE_Y] . '/' . $values[self::OPACITY] . '/'; + } return $url; } From 722b2f98d6a788ead08bd3bedb99fb00ee1cd84e Mon Sep 17 00:00:00 2001 From: Baspa Date: Fri, 30 Sep 2022 14:15:32 +0000 Subject: [PATCH 05/13] Fix styling --- src/Transformations.php | 43 +++++++++++++++++---------------- src/Transformations/Overlay.php | 40 +++++++++++++++--------------- 2 files changed, 42 insertions(+), 41 deletions(-) diff --git a/src/Transformations.php b/src/Transformations.php index 455ce6b..1f5e6d8 100644 --- a/src/Transformations.php +++ b/src/Transformations.php @@ -2,34 +2,34 @@ namespace Vormkracht10\UploadcareTransformations; +use Vormkracht10\UploadcareTransformations\Transformations\AutoRotate; +use Vormkracht10\UploadcareTransformations\Transformations\BasicColorAdjustments; use Vormkracht10\UploadcareTransformations\Transformations\Blur; +use Vormkracht10\UploadcareTransformations\Transformations\BlurFaces; +use Vormkracht10\UploadcareTransformations\Transformations\BlurRegion; +use Vormkracht10\UploadcareTransformations\Transformations\ConvertToSRGB; use Vormkracht10\UploadcareTransformations\Transformations\Crop; -use Vormkracht10\UploadcareTransformations\Transformations\Flip; +use Vormkracht10\UploadcareTransformations\Transformations\CropByObjects; +use Vormkracht10\UploadcareTransformations\Transformations\CropByRatio; +use Vormkracht10\UploadcareTransformations\Transformations\Enhance; use Vormkracht10\UploadcareTransformations\Transformations\Filter; +use Vormkracht10\UploadcareTransformations\Transformations\Flip; use Vormkracht10\UploadcareTransformations\Transformations\Format; +use Vormkracht10\UploadcareTransformations\Transformations\Grayscale; +use Vormkracht10\UploadcareTransformations\Transformations\ICCProfileSizeThreshold; use Vormkracht10\UploadcareTransformations\Transformations\Invert; use Vormkracht10\UploadcareTransformations\Transformations\Mirror; -use Vormkracht10\UploadcareTransformations\Transformations\Resize; -use Vormkracht10\UploadcareTransformations\Transformations\Rotate; -use Vormkracht10\UploadcareTransformations\Transformations\Enhance; use Vormkracht10\UploadcareTransformations\Transformations\Overlay; +use Vormkracht10\UploadcareTransformations\Transformations\Progressive; use Vormkracht10\UploadcareTransformations\Transformations\Quality; +use Vormkracht10\UploadcareTransformations\Transformations\Resize; +use Vormkracht10\UploadcareTransformations\Transformations\Rotate; +use Vormkracht10\UploadcareTransformations\Transformations\ScaleCrop; use Vormkracht10\UploadcareTransformations\Transformations\SetFill; use Vormkracht10\UploadcareTransformations\Transformations\Sharpen; -use Vormkracht10\UploadcareTransformations\Transformations\BlurFaces; -use Vormkracht10\UploadcareTransformations\Transformations\Grayscale; -use Vormkracht10\UploadcareTransformations\Transformations\ScaleCrop; use Vormkracht10\UploadcareTransformations\Transformations\SmartCrop; -use Vormkracht10\UploadcareTransformations\Transformations\AutoRotate; -use Vormkracht10\UploadcareTransformations\Transformations\BlurRegion; -use Vormkracht10\UploadcareTransformations\Transformations\CropByRatio; -use Vormkracht10\UploadcareTransformations\Transformations\Progressive; use Vormkracht10\UploadcareTransformations\Transformations\SmartResize; use Vormkracht10\UploadcareTransformations\Transformations\ZoomObjects; -use Vormkracht10\UploadcareTransformations\Transformations\ConvertToSRGB; -use Vormkracht10\UploadcareTransformations\Transformations\CropByObjects; -use Vormkracht10\UploadcareTransformations\Transformations\BasicColorAdjustments; -use Vormkracht10\UploadcareTransformations\Transformations\ICCProfileSizeThreshold; class Transformations { @@ -429,7 +429,7 @@ public function mirror(): self /** * Adds an image overlay to the original image. - * + * * @param string $uuid * @param int|string|null $width, * @param int|string|null $height, @@ -441,11 +441,12 @@ public function mirror(): self */ public function overlay( string $uuid, - int|string|null $width = null, - int|string|null $height = null, - int|string|null $coordinateX = null, - int|string|null $coordinateY = null, - int|null $opacity = null): self + int|string|null $width = null, + int|string|null $height = null, + int|string|null $coordinateX = null, + int|string|null $coordinateY = null, + int|null $opacity = null + ): self { $this->transformations['overlay'] = Overlay::transform($uuid, $width, $height, $coordinateX, $coordinateY, $opacity); diff --git a/src/Transformations/Overlay.php b/src/Transformations/Overlay.php index cdc924a..c49fa4d 100644 --- a/src/Transformations/Overlay.php +++ b/src/Transformations/Overlay.php @@ -46,38 +46,38 @@ public static function generateUrl(string $url, array $values): string // Check if only uuid is set /** @todo add UUID checks */ // if (isset($values[self::UUID]) ) - + // Check if only width/height is passed. - if (isset($values[self::WIDTH]) && - isset($values[self::HEIGHT]) && - !isset($values[self::COORDINATE_X]) && - !isset($values[self::COORDINATE_Y])) { - return $url . '-/overlay/' . $values[self::WIDTH] . 'x' . $values[self::HEIGHT] . '/'; + if (isset($values[self::WIDTH]) && + isset($values[self::HEIGHT]) && + ! isset($values[self::COORDINATE_X]) && + ! isset($values[self::COORDINATE_Y])) { + return $url . '-/overlay/' . $values[self::WIDTH] . 'x' . $values[self::HEIGHT] . '/'; } // Check if only width/height and coordinateX is passed. - if (isset($values[self::WIDTH]) && - isset($values[self::HEIGHT]) && - isset($values[self::COORDINATE_X]) && - !isset($values[self::COORDINATE_Y])) { - return $url . '-/overlay/' . $values[self::WIDTH] . 'x' . $values[self::HEIGHT] . '/' . $values[self::COORDINATE_X] . '/'; + if (isset($values[self::WIDTH]) && + isset($values[self::HEIGHT]) && + isset($values[self::COORDINATE_X]) && + ! isset($values[self::COORDINATE_Y])) { + return $url . '-/overlay/' . $values[self::WIDTH] . 'x' . $values[self::HEIGHT] . '/' . $values[self::COORDINATE_X] . '/'; } // Check if only width/height and coordinates is passed. - if (isset($values[self::WIDTH]) && - isset($values[self::HEIGHT]) && - isset($values[self::COORDINATE_X]) && + if (isset($values[self::WIDTH]) && + isset($values[self::HEIGHT]) && + isset($values[self::COORDINATE_X]) && isset($values[self::COORDINATE_Y])) { - return $url . '-/overlay/' . $values[self::WIDTH] . 'x' . $values[self::HEIGHT] . '/' . $values[self::COORDINATE_X] . 'x' . $values[self::COORDINATE_Y] . '/'; + return $url . '-/overlay/' . $values[self::WIDTH] . 'x' . $values[self::HEIGHT] . '/' . $values[self::COORDINATE_X] . 'x' . $values[self::COORDINATE_Y] . '/'; } // Check if only width/height and coordinates and opacity is passed. - if (isset($values[self::WIDTH]) && - isset($values[self::HEIGHT]) && - isset($values[self::COORDINATE_X]) && - isset($values[self::COORDINATE_Y]) && + if (isset($values[self::WIDTH]) && + isset($values[self::HEIGHT]) && + isset($values[self::COORDINATE_X]) && + isset($values[self::COORDINATE_Y]) && isset($values[self::OPACITY])) { - return $url . '-/overlay/' . $values[self::WIDTH] . 'x' . $values[self::HEIGHT] . '/' . $values[self::COORDINATE_X] . 'x' . $values[self::COORDINATE_Y] . '/' . $values[self::OPACITY] . '/'; + return $url . '-/overlay/' . $values[self::WIDTH] . 'x' . $values[self::HEIGHT] . '/' . $values[self::COORDINATE_X] . 'x' . $values[self::COORDINATE_Y] . '/' . $values[self::OPACITY] . '/'; } return $url; From 4ce60c9d9cb3ef7e0bb949c3b5c17355fc6ff41e Mon Sep 17 00:00:00 2001 From: Bas van Dinther Date: Tue, 11 Oct 2022 16:15:00 +0200 Subject: [PATCH 06/13] Add UUID to transformation --- src/Transformations/Overlay.php | 49 +++++++++++++++++++++------------ 1 file changed, 31 insertions(+), 18 deletions(-) diff --git a/src/Transformations/Overlay.php b/src/Transformations/Overlay.php index c49fa4d..ddfffd8 100644 --- a/src/Transformations/Overlay.php +++ b/src/Transformations/Overlay.php @@ -16,11 +16,11 @@ class Overlay implements TransformationInterface public static function transform(...$args): array { $uuid = $args[0]; - $width = $args[1]; - $height = $args[2]; - $coordinateX = $args[3]; - $coordinateY = $args[4]; - $opacity = $args[5]; + $width = $args[1] ?? null; + $height = $args[2] ?? null; + $coordinateX = $args[3] ?? null; + $coordinateY = $args[4] ?? null; + $opacity = $args[5] ?? null; return [ self::UUID => $uuid, @@ -40,44 +40,57 @@ public static function validate(string $key, ...$args): ?bool public static function generateUrl(string $url, array $values): string { - // Every overlay parameter is optional and can be omitted. However, the order of parameter URL directives should be preserved. - // -/overlay/:uuid/:relative_dimensions/:relative_coordinates/:opacity/ - // Check if only uuid is set - /** @todo add UUID checks */ - // if (isset($values[self::UUID]) ) + if (isset($values[self::UUID]) && + ! isset($values[self::WIDTH]) && + ! isset($values[self::HEIGHT]) && + ! isset($values[self::COORDINATE_X]) && + ! isset($values[self::COORDINATE_Y]) && + ! isset($values[self::OPACITY])) { + // -/overlay/:uuid/ + $url .= '-/overlay/' . $values[self::UUID] . '/'; + } // Check if only width/height is passed. - if (isset($values[self::WIDTH]) && + if (isset($values[self::UUID]) && + isset($values[self::WIDTH]) && isset($values[self::HEIGHT]) && ! isset($values[self::COORDINATE_X]) && ! isset($values[self::COORDINATE_Y])) { - return $url . '-/overlay/' . $values[self::WIDTH] . 'x' . $values[self::HEIGHT] . '/'; + // -/overlay/:uuid/:relative_dimensions/ + return $url . '-/overlay/' . $values[self::UUID] . '/' . $values[self::WIDTH] . 'x' . $values[self::HEIGHT] . '/'; } // Check if only width/height and coordinateX is passed. - if (isset($values[self::WIDTH]) && + if (isset($values[self::UUID]) && + isset($values[self::WIDTH]) && isset($values[self::HEIGHT]) && isset($values[self::COORDINATE_X]) && ! isset($values[self::COORDINATE_Y])) { - return $url . '-/overlay/' . $values[self::WIDTH] . 'x' . $values[self::HEIGHT] . '/' . $values[self::COORDINATE_X] . '/'; + // -/overlay/:uuid/:relative_dimensions/:coordinateX/ + return $url . '-/overlay/' . $values[self::UUID] . '/' . $values[self::WIDTH] . 'x' . $values[self::HEIGHT] . '/' . $values[self::COORDINATE_X] . '/'; } // Check if only width/height and coordinates is passed. - if (isset($values[self::WIDTH]) && + if (isset($values[self::UUID]) && + isset($values[self::WIDTH]) && isset($values[self::HEIGHT]) && isset($values[self::COORDINATE_X]) && isset($values[self::COORDINATE_Y])) { - return $url . '-/overlay/' . $values[self::WIDTH] . 'x' . $values[self::HEIGHT] . '/' . $values[self::COORDINATE_X] . 'x' . $values[self::COORDINATE_Y] . '/'; + // -/overlay/:uuid/:relative_dimensions/:coordinateX/:coordinateY/ + return $url . '-/overlay/' . $values[self::UUID] . '/' . $values[self::WIDTH] . 'x' . $values[self::HEIGHT] . '/' . $values[self::COORDINATE_X] . 'x' . $values[self::COORDINATE_Y] . '/'; } // Check if only width/height and coordinates and opacity is passed. - if (isset($values[self::WIDTH]) && + if ( + isset($values[self::UUID]) && + isset($values[self::WIDTH]) && isset($values[self::HEIGHT]) && isset($values[self::COORDINATE_X]) && isset($values[self::COORDINATE_Y]) && isset($values[self::OPACITY])) { - return $url . '-/overlay/' . $values[self::WIDTH] . 'x' . $values[self::HEIGHT] . '/' . $values[self::COORDINATE_X] . 'x' . $values[self::COORDINATE_Y] . '/' . $values[self::OPACITY] . '/'; + // -/overlay/:uuid/:relative_dimensions/:coordinateX/:coordinateY/:opacity/ + return $url . '-/overlay/' . $values[self::UUID] . '/' . $values[self::WIDTH] . 'x' . $values[self::HEIGHT] . '/' . $values[self::COORDINATE_X] . 'x' . $values[self::COORDINATE_Y] . '/' . $values[self::OPACITY] . '/'; } return $url; From 1a91fd9ed2e142989da83e0a0972f40237bb58b2 Mon Sep 17 00:00:00 2001 From: Baspa Date: Tue, 11 Oct 2022 14:15:25 +0000 Subject: [PATCH 07/13] Fix styling --- src/Transformations.php | 3 +-- src/Transformations/Overlay.php | 10 +++++----- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/Transformations.php b/src/Transformations.php index 1f5e6d8..bc94065 100644 --- a/src/Transformations.php +++ b/src/Transformations.php @@ -446,8 +446,7 @@ public function overlay( int|string|null $coordinateX = null, int|string|null $coordinateY = null, int|null $opacity = null - ): self - { + ): self { $this->transformations['overlay'] = Overlay::transform($uuid, $width, $height, $coordinateX, $coordinateY, $opacity); return $this; diff --git a/src/Transformations/Overlay.php b/src/Transformations/Overlay.php index ddfffd8..f0bcf25 100644 --- a/src/Transformations/Overlay.php +++ b/src/Transformations/Overlay.php @@ -41,11 +41,11 @@ public static function validate(string $key, ...$args): ?bool public static function generateUrl(string $url, array $values): string { // Check if only uuid is set - if (isset($values[self::UUID]) && - ! isset($values[self::WIDTH]) && - ! isset($values[self::HEIGHT]) && - ! isset($values[self::COORDINATE_X]) && - ! isset($values[self::COORDINATE_Y]) && + if (isset($values[self::UUID]) && + ! isset($values[self::WIDTH]) && + ! isset($values[self::HEIGHT]) && + ! isset($values[self::COORDINATE_X]) && + ! isset($values[self::COORDINATE_Y]) && ! isset($values[self::OPACITY])) { // -/overlay/:uuid/ $url .= '-/overlay/' . $values[self::UUID] . '/'; From 7dcca66c5bed5a2ea1a648b07c6831cd9b29f51d Mon Sep 17 00:00:00 2001 From: Bas van Dinther Date: Tue, 11 Oct 2022 16:26:10 +0200 Subject: [PATCH 08/13] Validation (wip) --- src/Transformations/Overlay.php | 39 ++++++++++++++++++++++++++++++--- 1 file changed, 36 insertions(+), 3 deletions(-) diff --git a/src/Transformations/Overlay.php b/src/Transformations/Overlay.php index ddfffd8..165efd6 100644 --- a/src/Transformations/Overlay.php +++ b/src/Transformations/Overlay.php @@ -2,10 +2,14 @@ namespace Vormkracht10\UploadcareTransformations\Transformations; +use Vormkracht10\UploadcareTransformations\Traits\Validations; +use Vormkracht10\UploadcareTransformations\Transformations\Enums\Offset; use Vormkracht10\UploadcareTransformations\Transformations\Interfaces\TransformationInterface; class Overlay implements TransformationInterface { + use Validations; + public const UUID = 'uuid'; public const WIDTH = 'width'; public const HEIGHT = 'height'; @@ -22,6 +26,22 @@ public static function transform(...$args): array $coordinateY = $args[4] ?? null; $opacity = $args[5] ?? null; + if (is_string($width) && ! self::validate('width', $width)) { + throw new \InvalidArgumentException('Invalid width percentage'); + } + + if (is_string($height) && ! self::validate('height', $height)) { + throw new \InvalidArgumentException('Invalid height percentage'); + } + + if ($coordinateX && ! self::validate('coordinateX', $coordinateX)) { + throw new \InvalidArgumentException('Invalid coordinate X'); + } + + if ($coordinateY && ! self::validate('coordinateY', $coordinateY)) { + throw new \InvalidArgumentException('Invalid coordinate Y'); + } + return [ self::UUID => $uuid, self::WIDTH => $width, @@ -32,10 +52,23 @@ public static function transform(...$args): array ]; } - public static function validate(string $key, ...$args): ?bool + /** + * @todo add proper validation for both coordinates + * @see https://uploadcare.com/docs/transformations/image/overlay/#overlay-image + */ + public static function validate(string $key, ...$args): bool { - /** @todo add validation */ - return null; + $value = $args[0]; + + if ($key === self::COORDINATE_X && is_string($value)) { + return Offset::tryFrom($value) !== null; + } + + if ($key === self::WIDTH || $key === self::HEIGHT) { + return self::isValidPercentage($value); + } + + return false; } public static function generateUrl(string $url, array $values): string From ba5d174b0c20dd413c6393e6198032a66565b3d5 Mon Sep 17 00:00:00 2001 From: Baspa Date: Tue, 11 Oct 2022 14:26:49 +0000 Subject: [PATCH 09/13] Fix styling --- src/Transformations/Overlay.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Transformations/Overlay.php b/src/Transformations/Overlay.php index e7d7491..4c0f5b6 100644 --- a/src/Transformations/Overlay.php +++ b/src/Transformations/Overlay.php @@ -52,8 +52,8 @@ public static function transform(...$args): array ]; } - /** - * @todo add proper validation for both coordinates + /** + * @todo add proper validation for both coordinates * @see https://uploadcare.com/docs/transformations/image/overlay/#overlay-image */ public static function validate(string $key, ...$args): bool From 2aeed1115e4915f8e140f02018b81e92b40c80d6 Mon Sep 17 00:00:00 2001 From: Bas van Dinther Date: Tue, 25 Oct 2022 16:03:30 +0200 Subject: [PATCH 10/13] Update README --- README.md | 258 +++++++++++++++++++++++++++++++++--------------------- 1 file changed, 157 insertions(+), 101 deletions(-) diff --git a/README.md b/README.md index b4b6bc5..61e8d9b 100644 --- a/README.md +++ b/README.md @@ -8,50 +8,51 @@ Generate [Uploadcare](https://uploadcare.com/?via=vk10) image processing URLs to transform and process your images. No need to write or generate the URL yourself. Just pass the UUID of the file, optionally pass the custom CDN and chain the methods you want to apply and the package generates the URL for you. - -- [Requirements](#requirements) -- [Installation](#installation) -- [Usage](#usage) -- [Documentation](#documentation) - * [Using percentages or pixels as parameter](#using-percentages-or-pixels-as-parameter) - * [List of possible transformations](#list-of-possible-transformations) -- [Usage](#usage-1) - * [Auto rotate](#auto-rotate) - * [Basic color adjustments](#basic-color-adjustments) - * [Blur](#blur) - * [Blur faces](#blur-faces) - * [Blur region](#blur-region) - * [Convert to sRGB](#convert-to-srgb) - * [Crop](#crop) - * [Crop by objects](#crop-by-objects) - * [Crop by ratio](#crop-by-ratio) - * [Enhance](#enhance) - * [Filter](#filter) - * [Flip](#flip) - * [Format](#format) - * [Grayscale](#grayscale) - * [ICC profile size threshold](#icc-profile-size-threshold) - * [Invert](#invert) - * [Miror](#miror) - * [Preview](#preview) - * [Progressive](#progressive) - * [Quality](#quality) - * [Resize](#resize) - * [Rotate](#rotate) - * [Scale crop](#scale-crop) - * [Set fill](#set-fill) - * [Sharpen](#sharpen) - * [Smart crop](#smart-crop) - * [Smart resize](#smart-resize) - * [Zoom objects](#zoom-objects) -- [Testing](#testing) -- [Changelog](#changelog) -- [Contributing](#contributing) -- [Security Vulnerabilities](#security-vulnerabilities) -- [Credits](#credits) -- [License](#license) +- [Requirements](#requirements) +- [Installation](#installation) +- [Usage](#usage) +- [Documentation](#documentation) + - [Using percentages or pixels as parameter](#using-percentages-or-pixels-as-parameter) + - [List of possible transformations](#list-of-possible-transformations) +- [Usage](#usage-1) + - [Auto rotate](#auto-rotate) + - [Basic color adjustments](#basic-color-adjustments) + - [Blur](#blur) + - [Blur faces](#blur-faces) + - [Blur region](#blur-region) + - [Convert to sRGB](#convert-to-srgb) + - [Crop](#crop) + - [Crop by objects](#crop-by-objects) + - [Crop by ratio](#crop-by-ratio) + - [Enhance](#enhance) + - [Filter](#filter) + - [Flip](#flip) + - [Format](#format) + - [Grayscale](#grayscale) + - [ICC profile size threshold](#icc-profile-size-threshold) + - [Invert](#invert) + - [Miror](#miror) + - [Overlay](#overlay) + - [Preview](#preview) + - [Progressive](#progressive) + - [Quality](#quality) + - [Resize](#resize) + - [Rotate](#rotate) + - [Scale crop](#scale-crop) + - [Set fill](#set-fill) + - [Sharpen](#sharpen) + - [Smart crop](#smart-crop) + - [Smart resize](#smart-resize) + - [Zoom objects](#zoom-objects) +- [Testing](#testing) +- [Changelog](#changelog) +- [Contributing](#contributing) +- [Security Vulnerabilities](#security-vulnerabilities) +- [Credits](#credits) +- [License](#license) ## Requirements +
  • PHP 8.1+
@@ -96,7 +97,7 @@ echo $url; // https://example.com/cdn/12a3456b-c789-1234-1de2-3cfa83096e25/-/crop/320x50p/center/-/set_fill/ffffff ``` -If you prefer to use a shorter version you can also use the helper method: +If you prefer to use a shorter version you can also use the helper method: ```php $uuid = '12a3456b-c789-1234-1de2-3cfa83096e25'; @@ -112,14 +113,17 @@ echo $url; ``` ### Using the Laravel framework -When you are using the Laravel framework it might be better to define the CDN in your `.env` file and get the value from the `.env` file in a config file. You can create a dedicated `config/uploadcare` config or add it to the `config/services` file. + +When you are using the Laravel framework it might be better to define the CDN in your `.env` file and get the value from the `.env` file in a config file. You can create a dedicated `config/uploadcare` config or add it to the `config/services` file. Your `.env` file: + ```dotenv UPLOADCARE_CDN=https://example.com/cdn/ ``` Your `config/uploadcare.php` file: + ```php return [ 'cdn' => env('UPLOADCARE_CDN', 'https://ucarecdn.com'), @@ -127,6 +131,7 @@ return [ ``` In your code: + ```php $url = uc($uuid, config('uploadcare.cdn'))->crop(width: 320, height: '50p', offsetX: 'center')->setFill(color: 'ffffff'); ``` @@ -134,6 +139,7 @@ $url = uc($uuid, config('uploadcare.cdn'))->crop(width: 320, height: '50p', offs ## Documentation ### Using percentages or pixels as parameter + In some of the methods you can pass parameters in various ways. For example in the [scaleCrop()](/src/Transformations/ScaleCrop.php) method you can pass the offset in the form of a percentage or pixels. To make it easier to recognize when a pixel or percentage is used you can pass the parameters as following. ```php @@ -147,58 +153,64 @@ $url = $transformation->scaleCrop(width: 320, height: 320, offsetX: 50, offsetY: // https://example.com/cdn/12a3456b-c789-1234-1de2-3cfa83096e25/scale_crop/320x320/50x60/ ``` ->As stated in the Uploadcare Documentation, in URLs, % is an escape character and should be encoded with %25 escape sequence, e.g. /scale_crop/440x440/80%25,80%25/. For convenience, we can use the p shortcut for percent which doesn't require encoding. +> As stated in the Uploadcare Documentation, in URLs, % is an escape character and should be encoded with %25 escape sequence, e.g. /scale_crop/440x440/80%25,80%25/. For convenience, we can use the p shortcut for percent which doesn't require encoding. ### List of possible transformations -Each transformation follows the documentation on Uploadcare which you may find here. + +Each transformation follows the documentation on Uploadcare which you may find here. The current list of possible transformations and where to find the documentation: -| Transformation | Uploadcare Documentation link | -| ------------- |:-------------:| -| [Auto rotate](#auto-rotate) | Link | -| [Basic color adjustments](#basic-color-adjustments) | Link | -| [Blur](#blur) | Link | -| [Blur faces](#blur-faces) | Link | -| [Blur region](#blur-region) | Link | -| [Convert to sRGB](#convert-to-srgb) | Link | -| [Crop](#crop) | Link | -| [Crop by objects](#crop-by-objects) | Link | -| [Crop by ratio](#crop-by-ratio) | Link | -| [Enhance](#enhance) | Link | -| [Filter](#filter) | Link | -| [Flip](#flip) | Link | -| [Format](#format) | Link | -| [Grayscale](#grayscale) | Link | -| [ICC profile size threshold](#icc-profile-size-threshold)| Link | -| [Invert](#invert) | Link | -| [Miror](#miror) | Link | -| [Preview](#preview) | Link | -| [Progressive](#progressive) | Link | -| [Quality](#quality) | Link | -| [Resize](#resize) | Link | -| [Rotate](#rotate) | Link | -| [Scale crop](#scale-crop) | Link | -| [Set fill](#set-fill) | Link | -| [Sharpen](#sharpen) | Link | -| [Smart crop](#smart-crop) | Link | -| [Smart resize](#smart-resize) | Link | -| [Zoom objects](#zoom-objects) | Link | +| Transformation | Uploadcare Documentation link | +| --------------------------------------------------------- | :----------------------------------------------------------------------------------------------------------------------------: | +| [Auto rotate](#auto-rotate) | Link | +| [Basic color adjustments](#basic-color-adjustments) | Link | +| [Blur](#blur) | Link | +| [Blur faces](#blur-faces) | Link | +| [Blur region](#blur-region) | Link | +| [Convert to sRGB](#convert-to-srgb) | Link | +| [Crop](#crop) | Link | +| [Crop by objects](#crop-by-objects) | Link | +| [Crop by ratio](#crop-by-ratio) | Link | +| [Enhance](#enhance) | Link | +| [Filter](#filter) | Link | +| [Flip](#flip) | Link | +| [Format](#format) | Link | +| [Grayscale](#grayscale) | Link | +| [ICC profile size threshold](#icc-profile-size-threshold) | Link | +| [Invert](#invert) | Link | +| [Miror](#miror) | Link | +| [Overlay](#overlay) | Link | +| [Preview](#preview) | Link | +| [Progressive](#progressive) | Link | +| [Quality](#quality) | Link | +| [Resize](#resize) | Link | +| [Rotate](#rotate) | Link | +| [Scale crop](#scale-crop) | Link | +| [Set fill](#set-fill) | Link | +| [Sharpen](#sharpen) | Link | +| [Smart crop](#smart-crop) | Link | +| [Smart resize](#smart-resize) | Link | +| [Zoom objects](#zoom-objects) | Link | ## Usage ### Adding filename + Original filenames can be accessed via Uploadcare's REST API. This can be done by making a request to receive a JSON response with file parameters including `original_filename`. You can set an optional filename that users will see instead of the original name: + ```php $url = $transformation->autoRotate(false)->filename('my-filename.jpg'); // https://example.com/cdn/.../-/autorotate/no/my-filename.jpg ``` + > Please note that the filename should comply with file name conventions. For more more information about how to use filenames please check the Uploadcare API documentation. + ### Auto rotate -The default behavior goes with parsing EXIF tags of original images and rotating them according to the “Orientation” tag. Using `false` as parameter allows turning off the default behavior. - +The default behavior goes with parsing EXIF tags of original images and rotating them according to the “Orientation” tag. Using `false` as parameter allows turning off the default behavior. + ```php $url = $transformation->autoRotate(false); // https://example.com/cdn/.../-/autorotate/no/ @@ -208,6 +220,7 @@ $url = $transformation->autoRotate(true); ``` ### Basic color adjustments + The value parameter controls the strength of any applied adjustment. Ranges of the value parameter differ between operations. There also is a zero point for each operation — the value producing outputs equal to original images. Adjustment (color) must be one of the following values: `brightness`, `exposure`, `contrast`, `saturation`, `gamma`, `vibrance`, `warmth`. @@ -220,6 +233,7 @@ $url = $transformation->basicColorAdjustments(color: 'brightness', value: 50); ``` ### Blur + Blurs images by the strength factor. The filtering mode is Gaussian Blur, where strength parameter sets the blur radius — effect intensity. ```php @@ -228,18 +242,20 @@ $url = $transformation->blur(strength: 50, amount: null); ``` ### Blur faces + When faces is specified the regions are selected automatically by utilizing face detection. - + ```php $url = $transformation->blurFaces(strength: 50); // https://example.com/cdn/.../-/blur_faces/50/ ``` -### Blur region +### Blur region + Blurs the specified region of the image by the strength factor. The filtering mode is Gaussian Blur, where strength parameter sets the blur radius — effect intensity. Dimensions and coordinates must be pixels or percentages. - + ```php // Using pixels. $url = $transformation->blurRegion(dimensionX: 250, dimensionY: 250, coordinateX: 50, coordinateY: 50, strength: 200); @@ -251,7 +267,8 @@ $url = $transformation->blurRegion(dimensionX: '50p', dimensionY: '50p', coordin ``` ### Convert to sRGB -The operation sets how Uploadcare behaves depending on different color profiles of uploaded images. See the [Uploadcare Documentation](https://uploadcare.com/docs/transformations/image/colors/#operation-srgb) to learn more about the possible outcomes. + +The operation sets how Uploadcare behaves depending on different color profiles of uploaded images. See the [Uploadcare Documentation](https://uploadcare.com/docs/transformations/image/colors/#operation-srgb) to learn more about the possible outcomes. The profile parameter must be one of the following values: `fast`, `icc`, `keep_profile`. @@ -261,11 +278,12 @@ $url = $transformation->convertToSRGB(profile: 'icc'); ``` ### Crop -Crops an image by using specified dimensions and alignment. + +Crops an image by using specified dimensions and alignment. Dimensions parameters can be in pixels or percentages. To see how pixels or percentages can be used, see the [Using percentages or pixels as parameter](#using-percentages-or-pixels-as-parameter) paragraph. -Alignment can also be in pixels and percentages but also a shortcut can be used. The possible values are: `top`, `center`, `bottom`, `left`, `right`. +Alignment can also be in pixels and percentages but also a shortcut can be used. The possible values are: `top`, `center`, `bottom`, `left`, `right`. ```php // Using percentages and a shortcut. @@ -281,10 +299,11 @@ $url = $transformation->crop(width: 100, height: '50p', offsetX: '25p', offsetY: // https://example.com/cdn/.../-/crop/100x50p/25p,25p/ ``` -### Crop by objects +### Crop by objects + Crops the image to the object specified by the tag parameter. -Tag can be one of `face` or `image`. +Tag can be one of `face` or `image`. Ratio are two numbers greater than zero separated by :. Ratio is the quotient from the division of these numbers. @@ -292,7 +311,6 @@ Dimensions and alignment must be set in percentages. In case of the alignment yo > Dimensions should be relative when used with a tag. So you are required to set both width and height with pixels. - ```php // Using no ratio, percentages and pixels combined. $url = $transformation->cropByObjects(tag: 'face', ratio: null, width: '50p', height: '50p'); @@ -303,7 +321,8 @@ $url = $transformation->cropByObjects(tag: 'face', ratio: '4:3', width: '50p', h // https://example.com/cdn/../-/crop/face/4:3/50px50p/bottom/ ``` -### Crop by ratio +### Crop by ratio + Crops the image to the specified aspect ratio, cutting off the rest of the image. Ratio are two numbers greater than zero separated by :. Ratio is the quotient from the division of these numbers. @@ -321,6 +340,7 @@ $url = $transformation->cropByRatio(ratio: '4:3', offsetX: '50p', offsetY: 240); ``` ### Enhance + Auto-enhances an image by performing the following operations: auto levels, auto contrast, and saturation sharpening. Strength must be a number between 0 and 100. Default value is 50. @@ -330,7 +350,8 @@ $url = $transformation->enhance(strength: 50); // https://example.com/cdn/.../-/enhance/50/ ``` -### Filter +### Filter + Applies one of predefined photo filters by its name. The way your images look affects their engagement rates. You apply filters thus providing beautiful images consistent across content pieces you publish. The name parameter should be one of the following: `adaris`, `briaril`, `calarel`, `carris`, `cynarel`, `cyren`, `elmet`, `elonni`, `enzana`, `erydark`, `fenralan`, `ferand`, `galen`, `gavin`, `gethriel`, `iorill`, `iothari`, `iselva`, `jadis`, `lavra`, `misiara`, `namala`, `nerion`, `nethari`, `pamaya`, `sarnar`, `sedis`, `sewen`, `sorahel`, `sorlen`, `tarian`, `thellassan`, `varriel`, `varven`, `vevera`, `virkas`, `yedis`, `yllara`, `zatvel`, `zevcen`. @@ -342,15 +363,17 @@ $url = $transformation->filter(name: 'adaris', value: 50); // https://example.com/cdn/.../-/filter/adaris/50/ ``` -### Flip +### Flip + Flips images. -```php +```php $url = $transformation->flip(); // https://example.com/cdn/.../-/flip/ ``` ### Format + Converts an image to one of the following formats: `jpg`, `png`, `webp`, `auto`. ```php @@ -358,7 +381,8 @@ $url = $transformation->format(format: 'jpeg'); // https://example.com/cdn/.../-/format/jpg/ ``` -### Grayscale +### Grayscale + Desaturates images. The operation has no additional parameters and simply produces a grayscale image output when applied. ```php @@ -367,9 +391,11 @@ $url = $transformation->grayscale(); ``` ### ICC profile size threshold + The operation defines which RGB color profile sizes will be considered “small” and “large” when using srgb in `fast` or `icc` modes. The `number` stands for the ICC profile size in kilobytes. The default value is 10 (10240 bytes). Most of the common RGB profile sizes (sRGB, Display P3, ProPhoto, Adobe RGB, Apple RGB) are below the threshold. + > Please note, that because this transformation should always be used in combination with [`convertToSRGB()`](#convert-to-srgb) its method should be called after `convertToSRGB()`. Otherwise the ICC profile size threshold gets overwritten by the `convertToSRGB()` transformation. ```php @@ -377,17 +403,17 @@ $url = $transformation->convertToSRGB(profile: 'fast')->iccProfileSizeThreshold( // https://example.com/cdn/.../-/max_icc_size/10/srgb/fast/ ``` +### Invert - -### Invert Inverts images rendering a 'negative' of the input. - + ```php $url = $transformation->invert(); // https://example.com/cdn/.../-/invert/ ``` ### Miror + Mirrors images. ```php @@ -395,14 +421,37 @@ $url = $transformation->mirror(); // https://example.com/cdn/.../-/mirror/ ``` +### Overlay + +The overlay operation allows to layer images one over another. One of the most common use cases here are watermarks: semi-transparent images layered over opaque ones to complicate their unauthorized usage, etc. + +> Every overlay parameter is optional and can be omitted. However, the order of parameter URL directives should be preserved. For example, if you want to use `coordinateX` parameter, you should also specify `width` and `height` parameters. + +```php +$uuidOverlay = 'e6b0c1c0-1b1a-4b1a-9b1a-1b1a1b1a1b1a'; + +$url = $transformation->overlay( + uuid: $uuidOverlay, + width: 150, + height: 150, + coordinateX: 200, + coordinateY: 300, + opacity: 25 +)->getUrl(); +// https://example.com/cdn/.../-/overlay/e6b0c1c0-1b1a-4b1a-9b1a-1b1a1b1a1b1a/150x150/200,300/25/ +``` + ### Preview + Downscales an image proportionally to fit the given width and height in pixels. + ```php $url = $transformation->preview(width: 100, height: 100); // https://example.com/cdn/.../-/preview/100x100/ ``` ### Progressive + Returns a progressive image. In progressive images, data are compressed in multiple passes of progressively higher detail. The operation does not affect non-JPEG images; does not force image formats to JPEG. ```php @@ -414,6 +463,7 @@ $url = $transformation->progressive(false); ``` ### Quality + Sets output JPEG and WebP quality. Since actual settings vary from codec to codec, and more importantly, from format to format, we provide five simple tiers and two automatic values which suits most cases of image distribution and are consistent. Quality must be one of the following values: `smart`, `smart_retina`, `normal`, `better`, `best`, `lighter`, `lightest`. @@ -424,19 +474,21 @@ $url = $transformation->quality(quality: 'smart'); ``` ### Resize + Resizes an image to one or two dimensions. When you set both width and height explicitly, it may result in a distorted image. If you specify either side, this operation will preserve the original aspect ratio and resize the image accordingly. Mode should be one of the following values: `on`, `off`, `fill`. ```php -// Using width, height, stretch and 'fill' mode. +// Using width, height, stretch and 'fill' mode. $url = $transformation->resize(width: 100, height: null, stretch: true, mode: 'fill'); // https://example.com/cdn/.../-/resize/100x/stretch/fill/ -// Using only height, no stretch and no mode. +// Using only height, no stretch and no mode. $url = $transformations->resize(width: null, height: 250, stretch: false); // https://example.com/cdn/.../-/resize/250x/ ``` ### Rotate + Right-angle image rotation, counterclockwise. The value of angle must be a multiple of 90. ```php @@ -445,6 +497,7 @@ $url = $transformation->rotate(angle: 180); ``` ### Scale crop + Scales an image until it fully covers the specified dimensions; the rest gets cropped. Mostly used to place images with various dimensions into placeholders (e.g., square shaped). Dimensions must be set in pixels. @@ -461,7 +514,8 @@ $url = $transformation->scaleCrop(width: 100, height: 100, offsetX: 'bottom'); // https://example.com/cdn/../-/scale_crop/100x100/bottom/ ``` -### Set fill +### Set fill + Sets the fill color used with crop, stretch or when converting an alpha channel enabled image to JPEG. Color must be a hex color code without using the hashtag. @@ -472,6 +526,7 @@ $url = $transformation->setFill(color: 'ff0000'); ``` ### Sharpen + Sharpens an image, might be especially useful with images that were subjected to downscaling. strength can be in the range from 0 to 20 and defaults to the value of 5. ```php @@ -480,6 +535,7 @@ $url = $transformation->sharpen(strength: 20); ``` ### Smart crop + Switching the crop type to one of the smart modes enables the content-aware mechanics. Uploadcare applies AI-based algorithms to detect faces and other visually sensible objects to crop the background and not the main object. Dimensions must be set in pixels. @@ -499,6 +555,7 @@ $url = $transformation->smartCrop(width: 100, height: 100, type: 'smart_faces_ob ``` ### Smart resize + Content-aware resize helps retaining original proportions of faces and other visually sensible objects while resizing the rest of the image using intelligent algorithms. ```php @@ -507,17 +564,16 @@ $url = $transformation->smartResize(width: 500, height: 500); ``` ### Zoom objects + Zoom objects operation is best suited for images with solid or uniform backgrounds. Zoom must be a number between 1 and 100. -```php +```php $url = $transformation->zoomObjects(zoom: 50); // https://example.com/cdn/.../-/zoom_objects/50/ ``` - - ## Testing ```bash From 9a1d0563d542f82c570221302d7b1a1d19d4e8ef Mon Sep 17 00:00:00 2001 From: Bas van Dinther Date: Tue, 25 Oct 2022 16:03:39 +0200 Subject: [PATCH 11/13] Improve validation and url generation --- src/Transformations/Overlay.php | 47 ++++++++++++++++++--------------- 1 file changed, 26 insertions(+), 21 deletions(-) diff --git a/src/Transformations/Overlay.php b/src/Transformations/Overlay.php index 4c0f5b6..508e7e0 100644 --- a/src/Transformations/Overlay.php +++ b/src/Transformations/Overlay.php @@ -64,6 +64,10 @@ public static function validate(string $key, ...$args): bool return Offset::tryFrom($value) !== null; } + if ($key === self::COORDINATE_X && is_int($value) || $key === self::COORDINATE_Y && is_int($value)) { + return true; + } + if ($key === self::WIDTH || $key === self::HEIGHT) { return self::isValidPercentage($value); } @@ -84,14 +88,26 @@ public static function generateUrl(string $url, array $values): string $url .= '-/overlay/' . $values[self::UUID] . '/'; } - // Check if only width/height is passed. + // Check if only width/height and coordinates and opacity is passed. + if ( + isset($values[self::UUID]) && + isset($values[self::WIDTH]) && + isset($values[self::HEIGHT]) && + isset($values[self::COORDINATE_X]) && + isset($values[self::COORDINATE_Y]) && + isset($values[self::OPACITY])) { + // -/overlay/:uuid/:relative_dimensions/:coordinateX/:coordinateY/:opacity/ + return $url . '-/overlay/' . $values[self::UUID] . '/' . $values[self::WIDTH] . 'x' . $values[self::HEIGHT] . '/' . $values[self::COORDINATE_X] . ',' . $values[self::COORDINATE_Y] . '/' . $values[self::OPACITY] . '/'; + } + + // Check if only width/height and coordinates is passed. if (isset($values[self::UUID]) && isset($values[self::WIDTH]) && isset($values[self::HEIGHT]) && - ! isset($values[self::COORDINATE_X]) && - ! isset($values[self::COORDINATE_Y])) { - // -/overlay/:uuid/:relative_dimensions/ - return $url . '-/overlay/' . $values[self::UUID] . '/' . $values[self::WIDTH] . 'x' . $values[self::HEIGHT] . '/'; + isset($values[self::COORDINATE_X]) && + isset($values[self::COORDINATE_Y])) { + // -/overlay/:uuid/:relative_dimensions/:coordinateX/:coordinateY/ + return $url . '-/overlay/' . $values[self::UUID] . '/' . $values[self::WIDTH] . 'x' . $values[self::HEIGHT] . '/' . $values[self::COORDINATE_X] . 'x' . $values[self::COORDINATE_Y] . '/'; } // Check if only width/height and coordinateX is passed. @@ -104,27 +120,16 @@ public static function generateUrl(string $url, array $values): string return $url . '-/overlay/' . $values[self::UUID] . '/' . $values[self::WIDTH] . 'x' . $values[self::HEIGHT] . '/' . $values[self::COORDINATE_X] . '/'; } - // Check if only width/height and coordinates is passed. + // Check if only width/height is passed. if (isset($values[self::UUID]) && isset($values[self::WIDTH]) && isset($values[self::HEIGHT]) && - isset($values[self::COORDINATE_X]) && - isset($values[self::COORDINATE_Y])) { - // -/overlay/:uuid/:relative_dimensions/:coordinateX/:coordinateY/ - return $url . '-/overlay/' . $values[self::UUID] . '/' . $values[self::WIDTH] . 'x' . $values[self::HEIGHT] . '/' . $values[self::COORDINATE_X] . 'x' . $values[self::COORDINATE_Y] . '/'; + ! isset($values[self::COORDINATE_X]) && + ! isset($values[self::COORDINATE_Y])) { + // -/overlay/:uuid/:relative_dimensions/ + return $url . '-/overlay/' . $values[self::UUID] . '/' . $values[self::WIDTH] . 'x' . $values[self::HEIGHT] . '/'; } - // Check if only width/height and coordinates and opacity is passed. - if ( - isset($values[self::UUID]) && - isset($values[self::WIDTH]) && - isset($values[self::HEIGHT]) && - isset($values[self::COORDINATE_X]) && - isset($values[self::COORDINATE_Y]) && - isset($values[self::OPACITY])) { - // -/overlay/:uuid/:relative_dimensions/:coordinateX/:coordinateY/:opacity/ - return $url . '-/overlay/' . $values[self::UUID] . '/' . $values[self::WIDTH] . 'x' . $values[self::HEIGHT] . '/' . $values[self::COORDINATE_X] . 'x' . $values[self::COORDINATE_Y] . '/' . $values[self::OPACITY] . '/'; - } return $url; } From 118f720d7e8bba9f2b17c8bfd9625ed905d713ab Mon Sep 17 00:00:00 2001 From: Bas van Dinther Date: Tue, 25 Oct 2022 16:20:12 +0200 Subject: [PATCH 12/13] Add tests, update README and fix validation --- README.md | 6 +++--- src/Transformations.php | 2 +- src/Transformations/Overlay.php | 14 ++++++------- tests/TransformationTest.php | 35 +++++++++++++++++++++++++++++++++ 4 files changed, 46 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 61e8d9b..e8b0b48 100644 --- a/README.md +++ b/README.md @@ -425,7 +425,7 @@ $url = $transformation->mirror(); The overlay operation allows to layer images one over another. One of the most common use cases here are watermarks: semi-transparent images layered over opaque ones to complicate their unauthorized usage, etc. -> Every overlay parameter is optional and can be omitted. However, the order of parameter URL directives should be preserved. For example, if you want to use `coordinateX` parameter, you should also specify `width` and `height` parameters. +> Every overlay parameter is optional and can be omitted. However, the order of parameter URL directives should be preserved. For example, if you want to use `coordinateX` parameter, you should also specify `width` and `height` parameters. Also note that the `opacity` parameter should be specified with percentages. ```php $uuidOverlay = 'e6b0c1c0-1b1a-4b1a-9b1a-1b1a1b1a1b1a'; @@ -436,9 +436,9 @@ $url = $transformation->overlay( height: 150, coordinateX: 200, coordinateY: 300, - opacity: 25 + opacity: '25p' )->getUrl(); -// https://example.com/cdn/.../-/overlay/e6b0c1c0-1b1a-4b1a-9b1a-1b1a1b1a1b1a/150x150/200,300/25/ +// https://example.com/cdn/.../-/overlay/e6b0c1c0-1b1a-4b1a-9b1a-1b1a1b1a1b1a/150x150/200,300/25p/ ``` ### Preview diff --git a/src/Transformations.php b/src/Transformations.php index ddc5f68..77e5c9d 100644 --- a/src/Transformations.php +++ b/src/Transformations.php @@ -446,7 +446,7 @@ public function overlay( int|string|null $height = null, int|string|null $coordinateX = null, int|string|null $coordinateY = null, - int|null $opacity = null + string|null $opacity = null ): self { $this->transformations['overlay'] = Overlay::transform($uuid, $width, $height, $coordinateX, $coordinateY, $opacity); diff --git a/src/Transformations/Overlay.php b/src/Transformations/Overlay.php index 508e7e0..6b8629a 100644 --- a/src/Transformations/Overlay.php +++ b/src/Transformations/Overlay.php @@ -42,6 +42,10 @@ public static function transform(...$args): array throw new \InvalidArgumentException('Invalid coordinate Y'); } + if ($opacity && !self::isValidPercentage($opacity)) { + throw new \InvalidArgumentException('Invalid opacity'); + } + return [ self::UUID => $uuid, self::WIDTH => $width, @@ -52,16 +56,12 @@ public static function transform(...$args): array ]; } - /** - * @todo add proper validation for both coordinates - * @see https://uploadcare.com/docs/transformations/image/overlay/#overlay-image - */ public static function validate(string $key, ...$args): bool { $value = $args[0]; - if ($key === self::COORDINATE_X && is_string($value)) { - return Offset::tryFrom($value) !== null; + if ($key === self::COORDINATE_X && is_string($value) || $key === self::COORDINATE_Y && is_string($value)) { + return Offset::tryFrom($value) !== null || self::isValidPercentage($value); } if ($key === self::COORDINATE_X && is_int($value) || $key === self::COORDINATE_Y && is_int($value)) { @@ -107,7 +107,7 @@ public static function generateUrl(string $url, array $values): string isset($values[self::COORDINATE_X]) && isset($values[self::COORDINATE_Y])) { // -/overlay/:uuid/:relative_dimensions/:coordinateX/:coordinateY/ - return $url . '-/overlay/' . $values[self::UUID] . '/' . $values[self::WIDTH] . 'x' . $values[self::HEIGHT] . '/' . $values[self::COORDINATE_X] . 'x' . $values[self::COORDINATE_Y] . '/'; + return $url . '-/overlay/' . $values[self::UUID] . '/' . $values[self::WIDTH] . 'x' . $values[self::HEIGHT] . '/' . $values[self::COORDINATE_X] . ',' . $values[self::COORDINATE_Y] . '/'; } // Check if only width/height and coordinateX is passed. diff --git a/tests/TransformationTest.php b/tests/TransformationTest.php index 85dc57d..f909913 100644 --- a/tests/TransformationTest.php +++ b/tests/TransformationTest.php @@ -121,3 +121,38 @@ $url = (string) $transformation->smartCrop(width: 200, height: 200, type: 'smart', offsetX: '50p', offsetY: '50p'); expect($url)->toBe('https://ucarecdn.com/12a3456b-c789-1234-1de2-3cfa83096e25/-/scale_crop/200x200/smart/50p,50p/'); }); + +it('can add an overlay', function () { + $uuid = '12a3456b-c789-1234-1de2-3cfa83096e25'; + $uuidOverlay = 'e6b0c1c0-1b1a-4b1a-9b1a-1b1a1b1a1b1a'; + + $transformation = uploadcare($uuid); + + // -/overlay/:uuid/ + $url = (string) $transformation->overlay($uuidOverlay); + expect($url)->toBe('https://ucarecdn.com/12a3456b-c789-1234-1de2-3cfa83096e25/-/overlay/e6b0c1c0-1b1a-4b1a-9b1a-1b1a1b1a1b1a/'); + + // -/overlay/:uuid/:relative_dimensions/:coordinateX/:coordinateY/:opacity/ + $url = (string) $transformation->overlay($uuidOverlay, width: 100, height: 100, coordinateX: 500, coordinateY: 300, opacity: '50p'); + expect($url)->toBe('https://ucarecdn.com/12a3456b-c789-1234-1de2-3cfa83096e25/-/overlay/e6b0c1c0-1b1a-4b1a-9b1a-1b1a1b1a1b1a/100x100/500,300/50p/'); + + // -/overlay/:uuid/:relative_dimensions/:coordinateX/:coordinateY/ + $url = (string) $transformation->overlay($uuidOverlay, width: 100, height: 100, coordinateX: 500, coordinateY: 300); + expect($url)->toBe('https://ucarecdn.com/12a3456b-c789-1234-1de2-3cfa83096e25/-/overlay/e6b0c1c0-1b1a-4b1a-9b1a-1b1a1b1a1b1a/100x100/500,300/'); + + // -/overlay/:uuid/:relative_dimensions/:coordinateX/:coordinateY/ + $url = (string) $transformation->overlay($uuidOverlay, width: 100, height: 100, coordinateX: '50p', coordinateY: '30p'); + expect($url)->toBe('https://ucarecdn.com/12a3456b-c789-1234-1de2-3cfa83096e25/-/overlay/e6b0c1c0-1b1a-4b1a-9b1a-1b1a1b1a1b1a/100x100/50p,30p/'); + + // -/overlay/:uuid/:relative_dimensions/:coordinateX/ + $url = (string) $transformation->overlay($uuidOverlay, width: 100, height: 100, coordinateX: 'center'); + expect($url)->toBe('https://ucarecdn.com/12a3456b-c789-1234-1de2-3cfa83096e25/-/overlay/e6b0c1c0-1b1a-4b1a-9b1a-1b1a1b1a1b1a/100x100/center/'); + + // -/overlay/:uuid/:relative_dimensions/ + $url = (string) $transformation->overlay($uuidOverlay, width: 100, height: 100); + expect($url)->toBe('https://ucarecdn.com/12a3456b-c789-1234-1de2-3cfa83096e25/-/overlay/e6b0c1c0-1b1a-4b1a-9b1a-1b1a1b1a1b1a/100x100/'); + + // Test if skipping one of the parameters results in missing the remaining parameters + $url = (string) $transformation->overlay($uuidOverlay, width: 100, height: 100, coordinateX: 500, coordinateY: null, opacity: '50p'); + expect($url)->toBe('https://ucarecdn.com/12a3456b-c789-1234-1de2-3cfa83096e25/-/overlay/e6b0c1c0-1b1a-4b1a-9b1a-1b1a1b1a1b1a/100x100/500/'); +}); From 1ba89aaad6573e3e1641049cc6a2d45fc4dd7ac0 Mon Sep 17 00:00:00 2001 From: Baspa Date: Tue, 25 Oct 2022 14:20:38 +0000 Subject: [PATCH 13/13] Fix styling --- src/Transformations/Overlay.php | 2 +- tests/TransformationTest.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Transformations/Overlay.php b/src/Transformations/Overlay.php index 6b8629a..d62b07e 100644 --- a/src/Transformations/Overlay.php +++ b/src/Transformations/Overlay.php @@ -42,7 +42,7 @@ public static function transform(...$args): array throw new \InvalidArgumentException('Invalid coordinate Y'); } - if ($opacity && !self::isValidPercentage($opacity)) { + if ($opacity && ! self::isValidPercentage($opacity)) { throw new \InvalidArgumentException('Invalid opacity'); } diff --git a/tests/TransformationTest.php b/tests/TransformationTest.php index f909913..d348724 100644 --- a/tests/TransformationTest.php +++ b/tests/TransformationTest.php @@ -147,7 +147,7 @@ // -/overlay/:uuid/:relative_dimensions/:coordinateX/ $url = (string) $transformation->overlay($uuidOverlay, width: 100, height: 100, coordinateX: 'center'); expect($url)->toBe('https://ucarecdn.com/12a3456b-c789-1234-1de2-3cfa83096e25/-/overlay/e6b0c1c0-1b1a-4b1a-9b1a-1b1a1b1a1b1a/100x100/center/'); - + // -/overlay/:uuid/:relative_dimensions/ $url = (string) $transformation->overlay($uuidOverlay, width: 100, height: 100); expect($url)->toBe('https://ucarecdn.com/12a3456b-c789-1234-1de2-3cfa83096e25/-/overlay/e6b0c1c0-1b1a-4b1a-9b1a-1b1a1b1a1b1a/100x100/');