diff --git a/Classes/Domain/Model/ImageSource.php b/Classes/Domain/Model/ImageSource.php
index a3ff756..f1d95d3 100644
--- a/Classes/Domain/Model/ImageSource.php
+++ b/Classes/Domain/Model/ImageSource.php
@@ -6,18 +6,20 @@
use Sitegeist\MediaComponents\Domain\Model\CropArea;
use Sitegeist\MediaComponents\Domain\Model\SourceSet;
use Sitegeist\MediaComponents\Interfaces\ConstructibleFromImage;
-use SMS\FluidComponents\Domain\Model\FalImage;
+use SMS\FluidComponents\Domain\Model\FalFile;
use SMS\FluidComponents\Domain\Model\Image;
use SMS\FluidComponents\Interfaces\ConstructibleFromArray;
use SMS\FluidComponents\Interfaces\ConstructibleFromExtbaseFile;
use SMS\FluidComponents\Interfaces\ConstructibleFromFileInterface;
use SMS\FluidComponents\Interfaces\ConstructibleFromInteger;
use SMS\FluidComponents\Interfaces\ConstructibleFromString;
+use SMS\FluidComponents\Interfaces\ImageWithCropVariants;
+use SMS\FluidComponents\Interfaces\ImageWithDimensions;
+use SMS\FluidComponents\Interfaces\ProcessableImage;
use SMS\FluidComponents\Utility\ComponentArgumentConverter;
use TYPO3\CMS\Core\Resource\FileInterface;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Extbase\Domain\Model\FileReference;
-use TYPO3\CMS\Extbase\Service\ImageService;
class ImageSource implements
ConstructibleFromArray,
@@ -32,8 +34,6 @@ class ImageSource implements
*/
protected ?Image $image = null;
- protected ?ImageService $imageService = null;
-
protected float $scale = 1.0;
protected ?CropArea $crop = null;
@@ -49,7 +49,6 @@ class ImageSource implements
public function __construct(
protected ?Image $originalImage = null
) {
- $this->imageService = GeneralUtility::makeInstance(ImageService::class);
$this->setCrop(new CropArea);
}
@@ -58,7 +57,7 @@ public static function fromArray(array $value): ImageSource
$argumentConverter = GeneralUtility::makeInstance(ComponentArgumentConverter::class);
try {
- $image = $argumentConverter->convertValueToType($value['originalImage'], Image::class);
+ $image = $argumentConverter->convertValueToType($value['originalImage'] ?? $value, Image::class);
} catch (\SMS\FluidComponents\Exception\InvalidArgumentException) {
// TODO better error handling here:
// Image is not required, but invalid combination of parameters should
@@ -76,20 +75,23 @@ public static function fromArray(array $value): ImageSource
if (isset($value['media'])) {
$imageSource->setMedia((string) $value['media']);
}
- if (isset($value['scale'])) {
+ if (isset($value['sizes'])) {
$imageSource->setSizes((string) $value['sizes']);
}
- if (isset($value['crop']) || isset($value['srcset'])) {
- $argumentConverter = GeneralUtility::makeInstance(ComponentArgumentConverter::class);
-
- if (isset($value['crop'])) {
- $imageSource->setCrop($argumentConverter->convertValueToType($value['crop'], CropArea::class));
- }
+ if (isset($value['crop'])) {
+ $imageSource->setCrop(
+ $argumentConverter->convertValueToType($value['crop'], CropArea::class)
+ );
+ } elseif ($image instanceof ImageWithCropVariants) {
+ $cropVariant = (isset($value['cropVariant']))
+ ? $image->getCropVariant($value['cropVariant'])
+ : $image->getDefaultCrop();
+ $imageSource->setCrop(new CropArea($cropVariant));
+ }
- if (isset($value['srcset'])) {
- $imageSource->setSrcset($argumentConverter->convertValueToType($value['srcset'], SourceSet::class));
- }
+ if (isset($value['srcset'])) {
+ $imageSource->setSrcset($argumentConverter->convertValueToType($value['srcset'], SourceSet::class));
}
return $imageSource;
@@ -164,6 +166,40 @@ public function setCrop(CropArea $crop): self
return $this;
}
+ public function getCroppedWidth(): ?int
+ {
+ if (!($this->originalImage instanceof ImageWithDimensions)) {
+ return null;
+ }
+
+ if ($this->crop->getArea()->isEmpty()) {
+ $this->originalImage->getWidth();
+ }
+
+ if ($this->getOriginalImage() instanceof FalFile) {
+ return (int) round($this->crop->getArea()->makeAbsoluteBasedOnFile($this->getOriginalImage()->getFile())->getWidth());
+ }
+
+ return (int) round($this->crop->getArea()->getWidth() * $this->originalImage->getWidth());
+ }
+
+ public function getCroppedHeight(): ?int
+ {
+ if (!($this->originalImage instanceof ImageWithDimensions)) {
+ return null;
+ }
+
+ if ($this->crop->getArea()->isEmpty()) {
+ $this->originalImage->getHeight();
+ }
+
+ if ($this->getOriginalImage() instanceof FalFile) {
+ return (int) round($this->crop->getArea()->makeAbsoluteBasedOnFile($this->getOriginalImage()->getFile())->getHeight());
+ }
+
+ return (int) round($this->crop->getArea()->getHeight() * $this->originalImage->getHeight());
+ }
+
public function getImage(): Image
{
// TODO throw exception if image is not defined
@@ -193,12 +229,14 @@ public function getDescription(): ?string
public function getHeight(): ?int
{
- return $this->getImage()->getHeight();
+ $image = $this->getImage();
+ return ($image instanceof ImageWithDimensions) ? $image->getHeight() : null;
}
public function getWidth(): ?int
{
- return $this->getImage()->getWidth();
+ $image = $this->getImage();
+ return ($image instanceof ImageWithDimensions) ? $image->getWidth() : null;
}
public function getMedia(): ?string
@@ -244,25 +282,17 @@ public function __toString(): string
protected function processImage(): void
{
- $originalImage = $this->getOriginalImage();
-
- if ($originalImage) {
- $crop = null;
- if ($this->getCrop()) {
- $cropArea = $this->getCrop()->getArea();
- if (!$cropArea->isEmpty()) {
- $crop = $cropArea->makeAbsoluteBasedOnFile($originalImage->getFile());
- }
- }
-
- $processingInstructions = [
- 'width' => round($originalImage->getWidth() * $this->getScale()),
- 'height' => round($originalImage->getHeight() * $this->getScale()),
- 'fileExtension' => $this->getFormat(),
- 'crop' => $crop
- ];
-
- $this->image = new FalImage($this->imageService->applyProcessingInstructions($originalImage->getFile(), $processingInstructions));
+ // TODO implement runtime cache
+ $this->image = null;
+
+ $original = $this->getOriginalImage();
+ if ($original instanceof ProcessableImage && $original instanceof ImageWithDimensions) {
+ $this->image = $original->process(
+ (int) round($this->getCroppedWidth() * $this->getScale()),
+ (int) round($this->getCroppedHeight() * $this->getScale()),
+ $this->getFormat(),
+ $this->getCrop()->getArea(),
+ );
}
}
}
diff --git a/Classes/ViewHelpers/Image/CropVariantViewHelper.php b/Classes/ViewHelpers/Image/CropVariantViewHelper.php
index e058579..583ba50 100644
--- a/Classes/ViewHelpers/Image/CropVariantViewHelper.php
+++ b/Classes/ViewHelpers/Image/CropVariantViewHelper.php
@@ -3,23 +3,31 @@
namespace Sitegeist\MediaComponents\ViewHelpers\Image;
-use TYPO3\CMS\Core\Imaging\ImageManipulation\Area;
-use TYPO3\CMS\Core\Imaging\ImageManipulation\CropVariantCollection;
-use TYPO3\CMS\Core\Resource\FileInterface;
+use Sitegeist\MediaComponents\Domain\Model\CropArea;
+use Sitegeist\MediaComponents\Domain\Model\ImageSource;
+use SMS\FluidComponents\Interfaces\ImageWithCropVariants;
+use SMS\FluidComponents\Interfaces\ImageWithDimensions;
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
class CropVariantViewHelper extends AbstractViewHelper
{
public function initializeArguments(): void
{
- $this->registerArgument('image', FileInterface::class, 'FAL file');
+ $this->registerArgument('image', ImageSource::class, 'Image object');
$this->registerArgument('name', 'string', 'name of the crop variant that should be used', false, 'default');
}
- public function render(): Area
+ public function render(): CropArea
{
$this->arguments['image'] ??= $this->renderChildren();
- $cropVariantCollection = CropVariantCollection::create((string)$this->arguments['image']->getProperty('crop'));
- return $cropVariantCollection->getCropArea($this->arguments['name']);
+ if (!($this->arguments['image']->getOriginalImage() instanceof ImageWithDimensions)) {
+ return $this->arguments['image'];
+ }
+
+ if ($this->arguments['image']->getOriginalImage() instanceof ImageWithCropVariants) {
+ return new CropArea($this->arguments['image']->getOriginalImage()->getCropVariant($this->arguments['name']));
+ } else {
+ return new CropArea;
+ }
}
}
diff --git a/Classes/ViewHelpers/Image/Modify/ScaleViewHelper.php b/Classes/ViewHelpers/Image/Modify/ScaleViewHelper.php
index d3bd581..7e309c4 100644
--- a/Classes/ViewHelpers/Image/Modify/ScaleViewHelper.php
+++ b/Classes/ViewHelpers/Image/Modify/ScaleViewHelper.php
@@ -24,8 +24,8 @@ public function render(): ImageSource
return $imageSource;
}
if ($this->arguments['height'] || $this->arguments['width']) {
- $heightFactor = $this->arguments['height'] ? $this->arguments['height'] / $imageSource->getOriginalImage()->getHeight() : 1;
- $widthFactor = $this->arguments['width'] ? $this->arguments['width'] / $imageSource->getOriginalImage()->getWidth() : 1;
+ $heightFactor = $this->arguments['height'] ? $this->arguments['height'] / $imageSource->getCroppedWidth() : 1;
+ $widthFactor = $this->arguments['width'] ? $this->arguments['width'] / $imageSource->getCroppedHeight() : 1;
$scaleFactor = ($this->arguments['maxDimensions'])
? min($heightFactor, $widthFactor)
: max($heightFactor, $widthFactor);
diff --git a/Classes/ViewHelpers/Image/SrcsetViewHelper.php b/Classes/ViewHelpers/Image/SrcsetViewHelper.php
index e340ec4..18d5064 100644
--- a/Classes/ViewHelpers/Image/SrcsetViewHelper.php
+++ b/Classes/ViewHelpers/Image/SrcsetViewHelper.php
@@ -5,8 +5,7 @@
use Sitegeist\MediaComponents\Domain\Model\ImageSource;
use Sitegeist\MediaComponents\Domain\Model\SourceSet;
-use TYPO3\CMS\Core\Utility\GeneralUtility;
-use TYPO3\CMS\Extbase\Service\ImageService;
+use SMS\FluidComponents\Interfaces\ImageWithDimensions;
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
class SrcsetViewHelper extends AbstractViewHelper
@@ -24,6 +23,11 @@ public function render(): string
return '';
}
$this->arguments['imageSource'] ??= $this->renderChildren();
+
+ if (!($this->arguments['imageSource']->getOriginalImage() instanceof ImageWithDimensions)) {
+ return '';
+ }
+
return self::generateSrcsetString($this->arguments['imageSource'], $this->arguments['srcset'], $this->arguments['base']);
}
@@ -32,12 +36,11 @@ public static function generateSrcsetString(ImageSource $imageSource, SourceSet
$output = [];
$base ??= $imageSource;
$widths = $srcset->getSrcsetAndWidths($base->getWidth());
- $imageService = GeneralUtility::makeInstance(ImageService::class);
$localImageSource = clone $imageSource;
foreach ($widths as $widthDescriptor => $width) {
- $localImageSource->setScale($width / $imageSource->getOriginalImage()->getWidth());
- $output[] = $imageService->getImageUri($localImageSource->getImage()->getFile()) . ' ' . $widthDescriptor;
+ $localImageSource->setScale($width / $localImageSource->getCroppedWidth());
+ $output[] = (string) $localImageSource . ' ' . $widthDescriptor;
}
return implode(', ', $output);
diff --git a/Resources/Private/Components/Image/Image.html b/Resources/Private/Components/Image/Image.html
index 2d9dc95..933713e 100644
--- a/Resources/Private/Components/Image/Image.html
+++ b/Resources/Private/Components/Image/Image.html
@@ -12,6 +12,7 @@
+
@@ -27,6 +28,9 @@
+
+
+
+
@@ -22,6 +23,9 @@
+
+
+