Skip to content

Commit b02ff69

Browse files
authored
Merge pull request #122 from sitegeist/task/imageWithDimensions
[FEATURE] Provide image dimensions in data structures
2 parents 76f978b + 2eed90a commit b02ff69

File tree

7 files changed

+148
-12
lines changed

7 files changed

+148
-12
lines changed

Classes/Domain/Model/FalImage.php

Lines changed: 36 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,18 @@
33
namespace SMS\FluidComponents\Domain\Model;
44

55
use SMS\FluidComponents\Domain\Model\Traits\FalFileTrait;
6+
use SMS\FluidComponents\Interfaces\ImageWithCropVariants;
7+
use SMS\FluidComponents\Interfaces\ImageWithDimensions;
8+
use SMS\FluidComponents\Interfaces\ProcessableImage;
9+
use TYPO3\CMS\Core\Imaging\ImageManipulation\Area;
10+
use TYPO3\CMS\Core\Imaging\ImageManipulation\CropVariantCollection;
11+
use TYPO3\CMS\Core\Utility\GeneralUtility;
12+
use TYPO3\CMS\Extbase\Service\ImageService;
613

714
/**
815
* Data structure as a wrapper around a FAL object to be passed to a component.
916
*/
10-
class FalImage extends Image
17+
class FalImage extends Image implements ImageWithDimensions, ImageWithCropVariants, ProcessableImage
1118
{
1219
use FalFileTrait;
1320

@@ -27,13 +34,37 @@ public function getCopyright(): ?string
2734
return parent::getCopyright() ?? $this->file->getProperty('copyright');
2835
}
2936

30-
public function getHeight()
37+
public function getHeight(): int
3138
{
32-
return $this->file->getProperty('height');
39+
return (int) $this->file->getProperty('height');
3340
}
3441

35-
public function getWidth()
42+
public function getWidth(): int
3643
{
37-
return $this->file->getProperty('width');
44+
return (int) $this->file->getProperty('width');
45+
}
46+
47+
public function getDefaultCrop(): Area
48+
{
49+
$cropVariantCollection = CropVariantCollection::create((string)$this->file->getProperty('crop'));
50+
return $cropVariantCollection->getCropArea();
51+
}
52+
53+
public function getCropVariant(string $name): Area
54+
{
55+
$cropVariantCollection = CropVariantCollection::create((string)$this->file->getProperty('crop'));
56+
return $cropVariantCollection->getCropArea($name);
57+
}
58+
59+
public function process(int $width, int $height, ?string $format, Area $cropArea): FalImage
60+
{
61+
$imageService = GeneralUtility::makeInstance(ImageService::class);
62+
$processedImage = $imageService->applyProcessingInstructions($this->getFile(), [
63+
'width' => $width,
64+
'height' => $height,
65+
'fileExtension' => $format,
66+
'crop' => ($cropArea->isEmpty()) ? null : $cropArea->makeAbsoluteBasedOnFile($this->getFile())
67+
]);
68+
return new FalImage($processedImage);
3869
}
3970
}

Classes/Domain/Model/LocalImage.php

Lines changed: 54 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,20 @@
22

33
namespace SMS\FluidComponents\Domain\Model;
44

5-
use SMS\FluidComponents\Exception\InvalidFilePathException;
6-
use TYPO3\CMS\Core\Utility\GeneralUtility;
75
use TYPO3\CMS\Core\Utility\PathUtility;
6+
use TYPO3\CMS\Core\Utility\GeneralUtility;
7+
use SMS\FluidComponents\Interfaces\ImageWithDimensions;
8+
use SMS\FluidComponents\Exception\InvalidFilePathException;
9+
use SMS\FluidComponents\Interfaces\ProcessableImage;
10+
use TYPO3\CMS\Core\Imaging\GraphicalFunctions;
11+
use TYPO3\CMS\Core\Imaging\ImageManipulation\Area;
812

913
/**
1014
* Data structure for a local image resource to be passed to a component.
1115
*
1216
* @deprecated, use FalImage instead
1317
*/
14-
class LocalImage extends Image
18+
class LocalImage extends Image implements ImageWithDimensions, ProcessableImage
1519
{
1620
/**
1721
* Type of image to differentiate implementations in Fluid templates.
@@ -23,6 +27,16 @@ class LocalImage extends Image
2327
*/
2428
protected string $filePath = '';
2529

30+
/**
31+
* Image width, will be determined at first access
32+
*/
33+
protected int $width = 0;
34+
35+
/**
36+
* Image height, will be determined at first access
37+
*/
38+
protected int $height = 0;
39+
2640
/**
2741
* Creates an image object for a local image resource.
2842
*
@@ -59,4 +73,41 @@ public function getPublicUrl(): string
5973
{
6074
return PathUtility::getAbsoluteWebPath($this->filePath);
6175
}
76+
77+
public function getHeight(): int
78+
{
79+
if (!isset($this->height)) {
80+
$this->getImageDimensions();
81+
}
82+
return $this->height;
83+
}
84+
85+
public function getWidth(): int
86+
{
87+
if (!isset($this->height)) {
88+
$this->getImageDimensions();
89+
}
90+
return $this->width;
91+
}
92+
93+
protected function getImageDimensions(): void
94+
{
95+
$graphicalFunctions = GeneralUtility::makeInstance(GraphicalFunctions::class);
96+
$imageDimensions = $graphicalFunctions->getImageDimensions($this->getFilePath());
97+
$this->width = (int) $imageDimensions[0];
98+
$this->height = (int) $imageDimensions[1];
99+
}
100+
101+
public function process(int $width, int $height, ?string $format, Area $cropArea): ProcessableImage
102+
{
103+
$imageService = GeneralUtility::makeInstance(ImageService::class);
104+
$file = $imageService->getImage($this->getFilePath(), null, false);
105+
$processedImage = $imageService->applyProcessingInstructions($file, [
106+
'width' => $width,
107+
'height' => $height,
108+
'fileExtension' => $format,
109+
'crop' => ($cropArea->isEmpty()) ? null : $cropArea->makeAbsoluteBasedOnFile($file)
110+
]);
111+
return new FalImage($processedImage);
112+
}
62113
}

Classes/Domain/Model/PlaceholderImage.php

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,14 @@
22

33
namespace SMS\FluidComponents\Domain\Model;
44

5+
use SMS\FluidComponents\Interfaces\ImageWithDimensions;
6+
use SMS\FluidComponents\Interfaces\ProcessableImage;
7+
use TYPO3\CMS\Core\Imaging\ImageManipulation\Area;
8+
59
/**
610
* Data structure for a placeholder image to be passed to a component.
711
*/
8-
class PlaceholderImage extends Image
12+
class PlaceholderImage extends Image implements ImageWithDimensions, ProcessableImage
913
{
1014
/**
1115
* Type of image to differentiate implementations in Fluid templates.
@@ -22,13 +26,19 @@ class PlaceholderImage extends Image
2226
*/
2327
protected int $height = 0;
2428

29+
/**
30+
* Image format of the image
31+
*/
32+
protected string $format = 'gif';
33+
2534
/**
2635
* Creates an image object for a placeholder image.
2736
*/
28-
public function __construct(int $width, int $height)
37+
public function __construct(int $width, int $height, string $format = 'gif')
2938
{
3039
$this->width = $width;
3140
$this->height = $height;
41+
$this->format = $format;
3242
}
3343

3444
public function getWidth(): int
@@ -41,8 +51,22 @@ public function getHeight(): int
4151
return $this->height;
4252
}
4353

54+
public function getFormat(): string
55+
{
56+
return $this->format;
57+
}
58+
4459
public function getPublicUrl(): string
4560
{
46-
return 'https://via.placeholder.com/' . $this->width . 'x' . $this->height;
61+
return 'https://via.placeholder.com/' . $this->width . 'x' . $this->height . '.' . $this->format;
62+
}
63+
64+
public function process(int $width, int $height, ?string $format, Area $cropArea): ProcessableImage
65+
{
66+
return new PlaceholderImage(
67+
(int) round($cropArea->getWidth() * $width),
68+
(int) round($cropArea->getHeight() * $height),
69+
$format ?: $this->format
70+
);
4771
}
4872
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?php
2+
3+
namespace SMS\FluidComponents\Interfaces;
4+
5+
use TYPO3\CMS\Core\Imaging\ImageManipulation\Area;
6+
7+
interface ImageWithCropVariants
8+
{
9+
public function getDefaultCrop(): Area;
10+
public function getCropVariant(string $name): Area;
11+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?php
2+
3+
namespace SMS\FluidComponents\Interfaces;
4+
5+
interface ImageWithDimensions
6+
{
7+
public function getHeight(): int;
8+
public function getWidth(): int;
9+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?php
2+
3+
namespace SMS\FluidComponents\Interfaces;
4+
5+
use TYPO3\CMS\Core\Imaging\ImageManipulation\Area;
6+
7+
interface ProcessableImage
8+
{
9+
public function process(int $width, int $height, ?string $format, Area $cropArea): ProcessableImage;
10+
}

Classes/Utility/ComponentArgumentConverter.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ public function canTypeBeConvertedToType(string $givenType, string $toType): arr
165165
// Check if the target type implements the constructor interface
166166
// required for conversion
167167
$conversionInfo = [];
168-
if (isset($this->conversionInterfaces[$givenType][0]) &&
168+
if (isset($this->conversionInterfaces[$givenType]) &&
169169
is_subclass_of($toType, $this->conversionInterfaces[$givenType][0])
170170
) {
171171
$conversionInfo = $this->conversionInterfaces[$givenType];

0 commit comments

Comments
 (0)