Completed
Push — master ( e9e88e...f5775a )
by Tim
25:21 queued 10:29
created

CropService::getFunctionName()   A

Complexity

Conditions 5
Paths 4

Size

Total Lines 24

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 24
rs 9.2248
c 0
b 0
f 0
cc 5
nc 4
nop 1
1
<?php
2
3
/**
4
 * Crop images.
5
 */
6
7
namespace HDNET\Focuspoint\Service;
8
9
use TYPO3\CMS\Core\Imaging\GraphicalFunctions;
10
use TYPO3\CMS\Core\Utility\CommandUtility;
11
use TYPO3\CMS\Core\Utility\GeneralUtility;
12
use TYPO3\CMS\Core\Utility\MathUtility;
13
use TYPO3\CMS\Core\Utility\PathUtility;
14
use TYPO3\CMS\Extbase\Reflection\ObjectAccess;
15
use TYPO3\CMS\Frontend\Imaging\GifBuilder;
16
use TYPO3\CMS\Core\Configuration\ExtensionConfiguration;
17
18
/**
19
 * Crop images.
20
 */
21
class CropService extends AbstractService
22
{
23
    /**
24
     * Create the crop version of the image.
25
     *
26
     * @param string $absoluteImageName
27
     * @param int    $focusWidth
28
     * @param int    $focusHeight
29
     * @param int    $sourceX
30
     * @param int    $sourceY
31
     * @param string $absoluteTempImageName
32
     */
33
    public function createImage(
34
        $absoluteImageName,
35
        $focusWidth,
36
        $focusHeight,
37
        $sourceX,
38
        $sourceY,
39
        $absoluteTempImageName
40
    ) {
41
        $fileExtension = \mb_strtolower(PathUtility::pathinfo($absoluteImageName, PATHINFO_EXTENSION));
42
        $function = $this->getFunctionName($fileExtension);
43
        $function = 'cropVia' . $function;
44
        $this->$function(
45
            $absoluteImageName,
46
            $focusWidth,
47
            $focusHeight,
48
            $sourceX,
49
            $sourceY,
50
            $absoluteTempImageName
51
        );
52
    }
53
54
    /**
55
     * Get the graphical function by file extension.
56
     *
57
     * @param string $fileExtension
58
     *
59
     * @return string
60
     */
61
    protected function getFunctionName(string $fileExtension): string
62
    {
63
        $validFunctions = [
64
            'GraphicalFunctions',
65
            'GifBuilder',
66
            'ImageMagick',
67
        ];
68
        $configuration = GeneralUtility::makeInstance(ExtensionConfiguration::class)->get('focuspoint');
69
        $functionConfiguration = $configuration['imageFunctionConfiguration'] ?? 'png:cropViaGifBuilder;*:GraphicalFunctions';
70
        $parts = GeneralUtility::trimExplode(';', $functionConfiguration, true);
71
        foreach ($parts as $part) {
72
            list($extensions, $function) = GeneralUtility::trimExplode(':', $part, true);
73
            if (!\in_array($function, $validFunctions, true)) {
74
                continue;
75
            }
76
77
            $extensions = GeneralUtility::trimExplode(',', $extensions, true);
78
            if (\in_array($fileExtension, $extensions, true) || \in_array('*', $extensions, true)) {
79
                return $function;
80
            }
81
        }
82
83
        return $validFunctions[0];
84
    }
85
86
    /**
87
     * Create the crop image (ImageMagikc/Gm).
88
     *
89
     * @param string $absoluteImageName
90
     * @param int    $focusWidth
91
     * @param int    $focusHeight
92
     * @param int    $sourceX
93
     * @param int    $sourceY
94
     * @param string $absoluteTempImageName
95
     */
96
    protected function cropViaImageMagick(
97
        $absoluteImageName,
98
        $focusWidth,
99
        $focusHeight,
100
        $sourceX,
101
        $sourceY,
102
        $absoluteTempImageName
103
    ) {
104
        $quality = MathUtility::forceIntegerInRange($GLOBALS['TYPO3_CONF_VARS']['GFX']['jpg_quality'], 10, 100, 75);
105
106
        $cropCommand = $focusWidth . 'x' . $focusHeight . '+' . $sourceX . '+' . $sourceY;
107
        $command = CommandUtility::imageMagickCommand(
108
            'convert',
109
            '-quality ' . $quality . ' ' . $absoluteImageName . ' -crop ' . $cropCommand . '  +repage ' . $absoluteTempImageName
110
        );
111
        CommandUtility::exec($command, $out);
112
    }
113
114
    /**
115
     * Create the crop image (GifBuilder).
116
     *
117
     * @param string $absoluteImageName
118
     * @param int    $focusWidth
119
     * @param int    $focusHeight
120
     * @param int    $sourceX
121
     * @param int    $sourceY
122
     * @param string $absoluteTempImageName
123
     */
124
    protected function cropViaGifBuilder(
125
        $absoluteImageName,
126
        $focusWidth,
127
        $focusHeight,
128
        $sourceX,
129
        $sourceY,
130
        $absoluteTempImageName
131
    ) {
132
        $size = \getimagesize($absoluteImageName);
133
        $relativeImagePath = \rtrim(PathUtility::getRelativePath(
134
            GeneralUtility::getIndpEnv('TYPO3_DOCUMENT_ROOT'),
135
            $absoluteImageName
136
        ), '/');
137
        // We need to pass maxWidth and maxHeight, which would otherwise fall back to 2000px, see:
138
        // https://github.com/TYPO3/TYPO3.CMS/blob/TYPO3_7-6/typo3/sysext/frontend/Classes/Imaging/GifBuilder.php#L367-L368
139
        $configuration = [
140
            'format' => \mb_strtolower(PathUtility::pathinfo($absoluteImageName, PATHINFO_EXTENSION)),
141
            'XY' => $size[0] . ',' . $size[1],
142
            'maxWidth' => $size[0],
143
            'maxHeight' => $size[1],
144
            'transparentBackground' => '1',
145
            '10' => 'IMAGE',
146
            '10.' => [
147
                'file' => $relativeImagePath,
148
                'file.' => [
149
                    'quality' => $GLOBALS['TYPO3_CONF_VARS']['GFX']['jpg_quality'],
150
                    'width' => $size[0],
151
                    'height' => $size[1],
152
                ],
153
            ],
154
            '20' => 'CROP',
155
            '20.' => [
156
                'crop' => $sourceX . ',' . $sourceY . ',' . $focusWidth . ',' . $focusHeight,
157
            ],
158
        ];
159
160
        /** @var GifBuilder $gifBuilder */
161
        $gifBuilder = GeneralUtility::makeInstance(GifBuilder::class);
162
        $gifBuilder->init();
163
        $gifBuilder->start($configuration, []);
164
        $gifBuilder->make();
165
        $gifBuilder->output($absoluteTempImageName);
166
        $gifBuilder->destroy();
167
    }
168
169
    /**
170
     * Create the crop image (GraphicalFunctions).
171
     *
172
     * @param string $absoluteImageName
173
     * @param int    $focusWidth
174
     * @param int    $focusHeight
175
     * @param int    $sourceX
176
     * @param int    $sourceY
177
     * @param string $absoluteTempImageName
178
     */
179
    protected function cropViaGraphicalFunctions(
180
        $absoluteImageName,
181
        $focusWidth,
182
        $focusHeight,
183
        $sourceX,
184
        $sourceY,
185
        $absoluteTempImageName
186
    ) {
187
        /** @var GraphicalFunctions $graphicalFunctions */
188
        $graphicalFunctions = GeneralUtility::makeInstance(GraphicalFunctions::class);
189
        $sourceImage = $graphicalFunctions->imageCreateFromFile($absoluteImageName);
190
        $destinationImage = \imagecreatetruecolor($focusWidth, $focusHeight);
191
192
        // prevent the problem of large images result in a "Allowed memory size" error
193
        // we do not need the alpha layer at all, because the PNG rendered with cropViaGraphicalFunctions
194
        ObjectAccess::setProperty($graphicalFunctions, 'saveAlphaLayer', true, true);
195
196
        $graphicalFunctions->imagecopyresized(
197
            $destinationImage,
198
            $sourceImage,
199
            0,
200
            0,
201
            $sourceX,
202
            $sourceY,
203
            $focusWidth,
204
            $focusHeight,
205
            $focusWidth,
206
            $focusHeight
207
        );
208
209
        $graphicalFunctions->ImageWrite(
210
            $destinationImage,
211
            $absoluteTempImageName,
212
            $GLOBALS['TYPO3_CONF_VARS']['GFX']['jpg_quality']
213
        );
214
    }
215
}
216