From e63bfeb6c4b38415e31e7c3bec938bb93e825a43 Mon Sep 17 00:00:00 2001 From: Martin Ficzel Date: Tue, 4 Jun 2024 22:23:24 +0200 Subject: [PATCH] WIP: Basic infrastructure for focal points in thumbnails and image variants No actual calculation yet --- .../Classes/Domain/Model/FocalPointTrait.php | 52 +++++++++++++++++++ .../Classes/Domain/Model/ImageVariant.php | 1 + Neos.Media/Classes/Domain/Model/Thumbnail.php | 1 + .../ImageThumbnailGenerator.php | 5 ++ .../Domain/Service/ThumbnailService.php | 12 +++++ .../Mysql/Version20240604184831.php | 36 +++++++++++++ 6 files changed, 107 insertions(+) create mode 100644 Neos.Media/Classes/Domain/Model/FocalPointTrait.php create mode 100644 Neos.Media/Migrations/Mysql/Version20240604184831.php diff --git a/Neos.Media/Classes/Domain/Model/FocalPointTrait.php b/Neos.Media/Classes/Domain/Model/FocalPointTrait.php new file mode 100644 index 00000000000..5ab519f3c66 --- /dev/null +++ b/Neos.Media/Classes/Domain/Model/FocalPointTrait.php @@ -0,0 +1,52 @@ +focalPointX; + } + + public function setFocalPointX(?int $focalPointX): void + { + $this->focalPointX = $focalPointX; + } + + public function getFocalPointY(): ?int + { + return $this->focalPointY; + } + + public function setFocalPointY(?int $focalPointY): void + { + $this->focalPointY = $focalPointY; + } +} diff --git a/Neos.Media/Classes/Domain/Model/ImageVariant.php b/Neos.Media/Classes/Domain/Model/ImageVariant.php index 01a6b6476a3..626935fc8f2 100644 --- a/Neos.Media/Classes/Domain/Model/ImageVariant.php +++ b/Neos.Media/Classes/Domain/Model/ImageVariant.php @@ -35,6 +35,7 @@ class ImageVariant extends Asset implements AssetVariantInterface, ImageInterface { use DimensionsTrait; + use FocalPointTrait; /** * @var ImageService diff --git a/Neos.Media/Classes/Domain/Model/Thumbnail.php b/Neos.Media/Classes/Domain/Model/Thumbnail.php index 56d3cf87c82..18168f4a88b 100644 --- a/Neos.Media/Classes/Domain/Model/Thumbnail.php +++ b/Neos.Media/Classes/Domain/Model/Thumbnail.php @@ -33,6 +33,7 @@ class Thumbnail implements ImageInterface { use DimensionsTrait; use QualityTrait; + use FocalPointTrait; /** * @var ThumbnailGeneratorStrategy diff --git a/Neos.Media/Classes/Domain/Model/ThumbnailGenerator/ImageThumbnailGenerator.php b/Neos.Media/Classes/Domain/Model/ThumbnailGenerator/ImageThumbnailGenerator.php index 8d8058cda3a..1710a6f5bff 100644 --- a/Neos.Media/Classes/Domain/Model/ThumbnailGenerator/ImageThumbnailGenerator.php +++ b/Neos.Media/Classes/Domain/Model/ThumbnailGenerator/ImageThumbnailGenerator.php @@ -57,6 +57,11 @@ public function canRefresh(Thumbnail $thumbnail) public function refresh(Thumbnail $thumbnail) { try { + /** + * @todo ... add additional crop to ensure that the focal point is + * in view after resizing ... needs common understanding wit + * the thumbnail service here: Packages/Neos/Neos.Media/Classes/Domain/Service/ThumbnailService.php:151 + */ $adjustments = [ new ResizeImageAdjustment( [ diff --git a/Neos.Media/Classes/Domain/Service/ThumbnailService.php b/Neos.Media/Classes/Domain/Service/ThumbnailService.php index 32843c971c3..0347e2c160e 100644 --- a/Neos.Media/Classes/Domain/Service/ThumbnailService.php +++ b/Neos.Media/Classes/Domain/Service/ThumbnailService.php @@ -20,6 +20,7 @@ use Neos\Flow\ResourceManagement\ResourceManager; use Neos\Media\Domain\Model\AssetInterface; use Neos\Media\Domain\Model\ImageInterface; +use Neos\Media\Domain\Model\ImageVariant; use Neos\Media\Domain\Model\Thumbnail; use Neos\Media\Domain\Model\ThumbnailConfiguration; use Neos\Media\Domain\Repository\ThumbnailRepository; @@ -147,6 +148,17 @@ public function getThumbnail(AssetInterface $asset, ThumbnailConfiguration $conf if ($thumbnail === null) { $thumbnail = new Thumbnail($asset, $configuration); + if ($asset instanceof ImageVariant) { + // @todo: needs common understanding of dimension change with resize adjustment + // - if a focal point was set + // - calculate target dimensions here + // - calculate new focalPointAfter transformation + // - store focal point in new image + // has to work closely with: Packages/Neos/Neos.Media/Classes/Domain/Model/ThumbnailGenerator/ImageThumbnailGenerator.php:58 + $thumbnail->setFocalPointX($asset->getFocalPointX() ? $asset->getFocalPointX() + 1 : null); + $thumbnail->setFocalPointY($asset->getFocalPointY() ? $asset->getFocalPointY() + 1 : null); + } + // If the thumbnail strategy failed to generate a valid thumbnail if ($async === false && $thumbnail->getResource() === null && $thumbnail->getStaticResource() === null) { // the thumbnail should not be persisted at this point, but remove is a no-op if the thumbnail diff --git a/Neos.Media/Migrations/Mysql/Version20240604184831.php b/Neos.Media/Migrations/Mysql/Version20240604184831.php new file mode 100644 index 00000000000..f7429b9014f --- /dev/null +++ b/Neos.Media/Migrations/Mysql/Version20240604184831.php @@ -0,0 +1,36 @@ +abortIf($this->connection->getDatabasePlatform()->getName() !== 'mysql', 'Migration can only be executed safely on "mysql".'); + + $this->addSql('ALTER TABLE neos_media_domain_model_imagevariant ADD focalpointx INT DEFAULT NULL, ADD focalpointy INT DEFAULT NULL'); + $this->addSql('ALTER TABLE neos_media_domain_model_thumbnail ADD focalpointx INT DEFAULT NULL, ADD focalpointy INT DEFAULT NULL'); + } + + public function down(Schema $schema): void + { + $this->abortIf($this->connection->getDatabasePlatform()->getName() !== 'mysql', 'Migration can only be executed safely on "mysql".'); + + $this->addSql('ALTER TABLE neos_media_domain_model_imagevariant DROP focalpointx, DROP focalpointy'); + $this->addSql('ALTER TABLE neos_media_domain_model_thumbnail DROP focalpointx, DROP focalpointy'); + + } +}