This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | namespace TraderInteractive\Util; |
||
4 | |||
5 | use Imagick; |
||
6 | use InvalidArgumentException; |
||
7 | use TraderInteractive\Util; |
||
8 | |||
9 | final class Image |
||
10 | { |
||
11 | /** |
||
12 | * @var string |
||
13 | */ |
||
14 | const DEFAULT_COLOR = 'white'; |
||
15 | |||
16 | /** |
||
17 | * @var bool |
||
18 | */ |
||
19 | const DEFAULT_UPSIZE = false; |
||
20 | |||
21 | /** |
||
22 | * @var bool |
||
23 | */ |
||
24 | const DEFAULT_BESTFIT = false; |
||
25 | |||
26 | /** |
||
27 | * @var int |
||
28 | */ |
||
29 | const DEFAULT_MAX_WIDTH = 10000; |
||
30 | |||
31 | /** |
||
32 | * @var int |
||
33 | */ |
||
34 | const DEFAULT_MAX_HEIGHT = 10000; |
||
35 | |||
36 | /** |
||
37 | * @var bool |
||
38 | */ |
||
39 | const DEFAULT_BLUR_BACKGROUND = false; |
||
40 | |||
41 | /** |
||
42 | * @var float |
||
43 | */ |
||
44 | const DEFAULT_BLUR_VALUE = 15.0; |
||
45 | |||
46 | /** |
||
47 | * @var array |
||
48 | */ |
||
49 | const DEFAULT_OPTIONS = [ |
||
50 | 'color' => self::DEFAULT_COLOR, |
||
51 | 'upsize' => self::DEFAULT_UPSIZE, |
||
52 | 'bestfit' => self::DEFAULT_BESTFIT, |
||
53 | 'maxWidth' => self::DEFAULT_MAX_WIDTH, |
||
54 | 'maxHeight' => self::DEFAULT_MAX_HEIGHT, |
||
55 | 'blurBackground' => self::DEFAULT_BLUR_BACKGROUND, |
||
56 | 'blurValue' => self::DEFAULT_BLUR_VALUE, |
||
57 | ]; |
||
58 | |||
59 | /** |
||
60 | * @param Imagick $source The image magick object to resize |
||
61 | * @param int $boxWidth The final width of the image. |
||
62 | * @param int $boxHeight The final height of the image. |
||
63 | * @param array $options Options for the resize operation. |
||
64 | * |
||
65 | * @return Imagick |
||
66 | * |
||
67 | * @throws \Exception Thrown if options are invalid. |
||
68 | */ |
||
69 | public static function resize(Imagick $source, int $boxWidth, int $boxHeight, array $options = []) : Imagick |
||
70 | { |
||
71 | $options += self::DEFAULT_OPTIONS; |
||
72 | |||
73 | $color = $options['color']; |
||
74 | Util::ensure(true, is_string($color), InvalidArgumentException::class, ['$options["color"] was not a string']); |
||
75 | |||
76 | $upsize = $options['upsize']; |
||
77 | Util::ensure(true, is_bool($upsize), InvalidArgumentException::class, ['$options["upsize"] was not a bool']); |
||
78 | |||
79 | $bestfit = $options['bestfit']; |
||
80 | Util::ensure(true, is_bool($bestfit), InvalidArgumentException::class, ['$options["bestfit"] was not a bool']); |
||
81 | |||
82 | $blurBackground = $options['blurBackground']; |
||
83 | Util::ensure( |
||
84 | true, |
||
85 | is_bool($blurBackground), |
||
86 | InvalidArgumentException::class, |
||
87 | ['$options["blurBackground"] was not a bool'] |
||
88 | ); |
||
89 | |||
90 | $blurValue = $options['blurValue']; |
||
91 | Util::ensure( |
||
92 | true, |
||
93 | is_float($blurValue), |
||
94 | InvalidArgumentException::class, |
||
95 | ['$options["blurValue"] was not a float'] |
||
96 | ); |
||
97 | $maxWidth = $options['maxWidth']; |
||
98 | Util::ensure(true, is_int($maxWidth), InvalidArgumentException::class, ['$options["maxWidth"] was not an int']); |
||
99 | |||
100 | $maxHeight = $options['maxHeight']; |
||
101 | Util::ensure( |
||
102 | true, |
||
103 | is_int($maxHeight), |
||
104 | InvalidArgumentException::class, |
||
105 | ['$options["maxHeight"] was not an int'] |
||
106 | ); |
||
107 | |||
108 | |||
109 | if ($boxWidth > $maxWidth || $boxWidth <= 0) { |
||
110 | throw new InvalidArgumentException('a $boxSizes width was not between 0 and $options["maxWidth"]'); |
||
111 | } |
||
112 | |||
113 | if ($boxHeight > $maxHeight || $boxHeight <= 0) { |
||
114 | throw new InvalidArgumentException('a $boxSizes height was not between 0 and $options["maxHeight"]'); |
||
115 | } |
||
116 | |||
117 | $clone = clone $source; |
||
118 | |||
119 | self::rotateImage($clone); |
||
120 | |||
121 | $width = $clone->getImageWidth(); |
||
122 | $height = $clone->getImageHeight(); |
||
123 | |||
124 | //ratio over 1 is horizontal, under 1 is vertical |
||
125 | $boxRatio = $boxWidth / $boxHeight; |
||
126 | //height should be positive since I didnt find a way you could get zero into imagick |
||
127 | $originalRatio = $width / $height; |
||
128 | |||
129 | $targetWidth = null; |
||
0 ignored issues
–
show
|
|||
130 | $targetHeight = null; |
||
0 ignored issues
–
show
$targetHeight is not used, you could remove the assignment.
This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently. $myVar = 'Value';
$higher = false;
if (rand(1, 6) > 3) {
$higher = true;
} else {
$higher = false;
}
Both the ![]() |
|||
131 | $targetX = null; |
||
0 ignored issues
–
show
$targetX is not used, you could remove the assignment.
This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently. $myVar = 'Value';
$higher = false;
if (rand(1, 6) > 3) {
$higher = true;
} else {
$higher = false;
}
Both the ![]() |
|||
132 | $targetY = null; |
||
0 ignored issues
–
show
$targetY is not used, you could remove the assignment.
This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently. $myVar = 'Value';
$higher = false;
if (rand(1, 6) > 3) {
$higher = true;
} else {
$higher = false;
}
Both the ![]() |
|||
133 | View Code Duplication | if ($width < $boxWidth && $height < $boxHeight && !$upsize) { |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
134 | $targetWidth = $width; |
||
135 | $targetHeight = $height; |
||
136 | $targetX = ($boxWidth - $width) / 2; |
||
137 | $targetY = ($boxHeight - $height) / 2; |
||
138 | } else { |
||
139 | //if box is more vertical than original |
||
140 | if ($boxRatio < $originalRatio) { |
||
141 | $targetWidth = $boxWidth; |
||
142 | $targetHeight = (int)((double)$boxWidth / $originalRatio); |
||
143 | $targetX = 0; |
||
144 | $targetY = ($boxHeight - $targetHeight) / 2; |
||
145 | } else { |
||
146 | $targetWidth = (int)((double)$boxHeight * $originalRatio); |
||
147 | $targetHeight = $boxHeight; |
||
148 | $targetX = ($boxWidth - $targetWidth) / 2; |
||
149 | $targetY = 0; |
||
150 | } |
||
151 | } |
||
152 | |||
153 | $widthReduced = false; |
||
154 | if ($width > $targetWidth) { |
||
155 | $width = $targetWidth; |
||
156 | $widthReduced = true; |
||
157 | } |
||
158 | |||
159 | $heightReduced = false; |
||
160 | if ($height > $targetHeight) { |
||
161 | $height = $targetHeight; |
||
162 | $heightReduced = true; |
||
163 | } |
||
164 | |||
165 | if ($widthReduced || $heightReduced) { |
||
166 | if ($clone->resizeImage($width, $height, \Imagick::FILTER_BOX, 1.0) !== true) { |
||
167 | //cumbersome to test |
||
168 | throw new \Exception('Imagick::resizeImage() did not return true');//@codeCoverageIgnore |
||
169 | } |
||
170 | } |
||
171 | |||
172 | View Code Duplication | if ($upsize && ($width < $targetWidth || $height < $targetHeight)) { |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
173 | if ($clone->resizeImage($targetWidth, $targetHeight, \Imagick::FILTER_CUBIC, 1.0, $bestfit) !== true) { |
||
174 | //cumbersome to test |
||
175 | throw new \Exception('Imagick::resizeImage() did not return true');//@codeCoverageIgnore |
||
176 | } |
||
177 | } |
||
178 | |||
179 | if ($clone->getImageHeight() === $boxHeight && $clone->getImageWidth() === $boxWidth) { |
||
180 | return $clone; |
||
181 | } |
||
182 | |||
183 | //put image in box |
||
184 | $canvas = self::getBackgroundCanvas($clone, $color, $blurBackground, $blurValue, $boxWidth, $boxHeight); |
||
185 | if ($canvas->compositeImage($clone, Imagick::COMPOSITE_DEFAULT, $targetX, $targetY) !== true) { |
||
186 | //cumbersome to test |
||
187 | throw new \Exception('Imagick::compositeImage() did not return true');//@codeCoverageIgnore |
||
188 | } |
||
189 | |||
190 | //reason we are not supporting the options in self::write() here is because format, and strip headers are |
||
191 | //only relevant once written Imagick::stripImage() doesnt even have an effect until written |
||
192 | //also the user can just call that function with the resultant $canvas |
||
193 | return $canvas; |
||
194 | } |
||
195 | |||
196 | /** |
||
197 | * resizes images into a bounding box. Maintains aspect ratio, extra space filled with given color. |
||
198 | * |
||
199 | * @param \Imagick $source source image to resize. Will not modify |
||
200 | * @param array $boxSizes resulting bounding boxes. Each value should be an array with width and height, both |
||
201 | * integers |
||
202 | * @param array $options options |
||
203 | * string color (default white) background color. Any supported from |
||
204 | * http://www.imagemagick.org/script/color.php#color_names |
||
205 | * bool upsize (default false) true to upsize the original image or false to upsize just the bounding box |
||
206 | * bool bestfit (default false) true to resize with the best fit option. |
||
207 | * int maxWidth (default 10000) max width allowed for $boxWidth |
||
208 | * int maxHeight (default 10000) max height allowed for $boxHeight |
||
209 | * bool blurBackground (default false) true to create a composite resized image placed over an enlarged blurred |
||
210 | * image of the original. |
||
211 | * |
||
212 | * @return array array of \Imagick objects resized. Keys maintained from $boxSizes |
||
213 | * |
||
214 | * @throws InvalidArgumentException if $options["color"] was not a string |
||
215 | * @throws InvalidArgumentException if $options["upsize"] was not a bool |
||
216 | * @throws InvalidArgumentException if $options["bestfit"] was not a bool |
||
217 | * @throws InvalidArgumentException if $options["maxWidth"] was not an int |
||
218 | * @throws InvalidArgumentException if $options["maxHeight"] was not an int |
||
219 | * @throws InvalidArgumentException if a width in a $boxSizes value was not an int |
||
220 | * @throws InvalidArgumentException if a height in a $boxSizes value was not an int |
||
221 | * @throws InvalidArgumentException if a $boxSizes width was not between 0 and $options["maxWidth"] |
||
222 | * @throws InvalidArgumentException if a $boxSizes height was not between 0 and $options["maxHeight"] |
||
223 | * @throws \Exception |
||
224 | */ |
||
225 | public static function resizeMulti(\Imagick $source, array $boxSizes, array $options = []) : array |
||
226 | { |
||
227 | //algorithm inspired from http://today.java.net/pub/a/today/2007/04/03/perils-of-image-getscaledinstance.html |
||
228 | //use of 2x2 binning is arguably the best quality one will get downsizing and is what lots of hardware does in |
||
229 | //the photography field, while being reasonably fast. Upsizing is more subjective but you can't get much |
||
230 | //better than bicubic which is what is used here. |
||
231 | |||
232 | $options = $options + self::DEFAULT_OPTIONS; |
||
233 | $color = $options['color']; |
||
234 | Util::ensure(true, is_string($color), InvalidArgumentException::class, ['$options["color"] was not a string']); |
||
235 | |||
236 | $upsize = $options['upsize']; |
||
237 | Util::ensure(true, is_bool($upsize), InvalidArgumentException::class, ['$options["upsize"] was not a bool']); |
||
238 | |||
239 | $bestfit = $options['bestfit']; |
||
240 | Util::ensure(true, is_bool($bestfit), InvalidArgumentException::class, ['$options["bestfit"] was not a bool']); |
||
241 | |||
242 | $blurBackground = $options['blurBackground']; |
||
243 | Util::ensure( |
||
244 | true, |
||
245 | is_bool($blurBackground), |
||
246 | InvalidArgumentException::class, |
||
247 | ['$options["blurBackground"] was not a bool'] |
||
248 | ); |
||
249 | |||
250 | $blurValue = $options['blurValue']; |
||
251 | Util::ensure( |
||
252 | true, |
||
253 | is_float($blurValue), |
||
254 | InvalidArgumentException::class, |
||
255 | ['$options["blurValue"] was not a float'] |
||
256 | ); |
||
257 | $maxWidth = $options['maxWidth']; |
||
258 | Util::ensure(true, is_int($maxWidth), InvalidArgumentException::class, ['$options["maxWidth"] was not an int']); |
||
259 | |||
260 | $maxHeight = $options['maxHeight']; |
||
261 | Util::ensure( |
||
262 | true, |
||
263 | is_int($maxHeight), |
||
264 | InvalidArgumentException::class, |
||
265 | ['$options["maxHeight"] was not an int'] |
||
266 | ); |
||
267 | |||
268 | foreach ($boxSizes as $boxSizeKey => $boxSize) { |
||
269 | View Code Duplication | if (!isset($boxSize['width']) || !is_int($boxSize['width'])) { |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
270 | throw new InvalidArgumentException('a width in a $boxSizes value was not an int'); |
||
271 | } |
||
272 | |||
273 | View Code Duplication | if (!isset($boxSize['height']) || !is_int($boxSize['height'])) { |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
274 | throw new InvalidArgumentException('a height in a $boxSizes value was not an int'); |
||
275 | } |
||
276 | |||
277 | if ($boxSize['width'] > $maxWidth || $boxSize['width'] <= 0) { |
||
278 | throw new InvalidArgumentException('a $boxSizes width was not between 0 and $options["maxWidth"]'); |
||
279 | } |
||
280 | |||
281 | if ($boxSize['height'] > $maxHeight || $boxSize['height'] <= 0) { |
||
282 | throw new InvalidArgumentException('a $boxSizes height was not between 0 and $options["maxHeight"]'); |
||
283 | } |
||
284 | } |
||
285 | |||
286 | $results = []; |
||
287 | $cloneCache = []; |
||
288 | foreach ($boxSizes as $boxSizeKey => $boxSize) { |
||
289 | $boxWidth = $boxSize['width']; |
||
290 | $boxHeight = $boxSize['height']; |
||
291 | |||
292 | $clone = clone $source; |
||
293 | |||
294 | self::rotateImage($clone); |
||
295 | |||
296 | $width = $clone->getImageWidth(); |
||
297 | $height = $clone->getImageHeight(); |
||
298 | |||
299 | //ratio over 1 is horizontal, under 1 is vertical |
||
300 | $boxRatio = $boxWidth / $boxHeight; |
||
301 | //height should be positive since I didnt find a way you could get zero into imagick |
||
302 | $originalRatio = $width / $height; |
||
303 | |||
304 | $targetWidth = null; |
||
0 ignored issues
–
show
$targetWidth is not used, you could remove the assignment.
This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently. $myVar = 'Value';
$higher = false;
if (rand(1, 6) > 3) {
$higher = true;
} else {
$higher = false;
}
Both the ![]() |
|||
305 | $targetHeight = null; |
||
0 ignored issues
–
show
$targetHeight is not used, you could remove the assignment.
This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently. $myVar = 'Value';
$higher = false;
if (rand(1, 6) > 3) {
$higher = true;
} else {
$higher = false;
}
Both the ![]() |
|||
306 | $targetX = null; |
||
0 ignored issues
–
show
$targetX is not used, you could remove the assignment.
This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently. $myVar = 'Value';
$higher = false;
if (rand(1, 6) > 3) {
$higher = true;
} else {
$higher = false;
}
Both the ![]() |
|||
307 | $targetY = null; |
||
0 ignored issues
–
show
$targetY is not used, you could remove the assignment.
This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently. $myVar = 'Value';
$higher = false;
if (rand(1, 6) > 3) {
$higher = true;
} else {
$higher = false;
}
Both the ![]() |
|||
308 | View Code Duplication | if ($width < $boxWidth && $height < $boxHeight && !$upsize) { |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
309 | $targetWidth = $width; |
||
310 | $targetHeight = $height; |
||
311 | $targetX = ($boxWidth - $width) / 2; |
||
312 | $targetY = ($boxHeight - $height) / 2; |
||
313 | } else { |
||
314 | //if box is more vertical than original |
||
315 | if ($boxRatio < $originalRatio) { |
||
316 | $targetWidth = $boxWidth; |
||
317 | $targetHeight = (int)((double)$boxWidth / $originalRatio); |
||
318 | $targetX = 0; |
||
319 | $targetY = ($boxHeight - $targetHeight) / 2; |
||
320 | } else { |
||
321 | $targetWidth = (int)((double)$boxHeight * $originalRatio); |
||
322 | $targetHeight = $boxHeight; |
||
323 | $targetX = ($boxWidth - $targetWidth) / 2; |
||
324 | $targetY = 0; |
||
325 | } |
||
326 | } |
||
327 | |||
328 | //do iterative downsize by halfs (2x2 binning is a common name) on dimensions that are bigger than target |
||
329 | //width and height |
||
330 | while (true) { |
||
331 | $widthReduced = false; |
||
332 | $widthIsHalf = false; |
||
333 | if ($width > $targetWidth) { |
||
334 | $width = (int)($width / 2); |
||
335 | $widthReduced = true; |
||
336 | $widthIsHalf = true; |
||
337 | if ($width < $targetWidth) { |
||
338 | $width = $targetWidth; |
||
339 | $widthIsHalf = false; |
||
340 | } |
||
341 | } |
||
342 | |||
343 | $heightReduced = false; |
||
344 | $heightIsHalf = false; |
||
345 | if ($height > $targetHeight) { |
||
346 | $height = (int)($height / 2); |
||
347 | $heightReduced = true; |
||
348 | $heightIsHalf = true; |
||
349 | if ($height < $targetHeight) { |
||
350 | $height = $targetHeight; |
||
351 | $heightIsHalf = false; |
||
352 | } |
||
353 | } |
||
354 | |||
355 | if (!$widthReduced && !$heightReduced) { |
||
356 | break; |
||
357 | } |
||
358 | |||
359 | $cacheKey = "{$width}x{$height}"; |
||
360 | if (isset($cloneCache[$cacheKey])) { |
||
361 | $clone = clone $cloneCache[$cacheKey]; |
||
362 | continue; |
||
363 | } |
||
364 | |||
365 | if ($clone->resizeImage($width, $height, \Imagick::FILTER_BOX, 1.0) !== true) { |
||
366 | //cumbersome to test |
||
367 | throw new \Exception('Imagick::resizeImage() did not return true');//@codeCoverageIgnore |
||
368 | } |
||
369 | |||
370 | if ($widthIsHalf && $heightIsHalf) { |
||
371 | $cloneCache[$cacheKey] = clone $clone; |
||
372 | } |
||
373 | } |
||
374 | |||
375 | View Code Duplication | if ($upsize && ($width < $targetWidth || $height < $targetHeight)) { |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
376 | if ($clone->resizeImage($targetWidth, $targetHeight, \Imagick::FILTER_CUBIC, 1.0, $bestfit) !== true) { |
||
377 | //cumbersome to test |
||
378 | throw new \Exception('Imagick::resizeImage() did not return true');//@codeCoverageIgnore |
||
379 | } |
||
380 | } |
||
381 | |||
382 | if ($clone->getImageHeight() === $boxHeight && $clone->getImageWidth() === $boxWidth) { |
||
383 | $results[$boxSizeKey] = $clone; |
||
384 | continue; |
||
385 | } |
||
386 | |||
387 | //put image in box |
||
388 | $canvas = self::getBackgroundCanvas($source, $color, $blurBackground, $blurValue, $boxWidth, $boxHeight); |
||
389 | if ($canvas->compositeImage($clone, \Imagick::COMPOSITE_ATOP, $targetX, $targetY) !== true) { |
||
390 | //cumbersome to test |
||
391 | throw new \Exception('Imagick::compositeImage() did not return true');//@codeCoverageIgnore |
||
392 | } |
||
393 | |||
394 | //reason we are not supporting the options in self::write() here is because format, and strip headers are |
||
395 | //only relevant once written Imagick::stripImage() doesnt even have an effect until written |
||
396 | //also the user can just call that function with the resultant $canvas |
||
397 | $results[$boxSizeKey] = $canvas; |
||
398 | } |
||
399 | |||
400 | foreach ($cloneCache as $clone) { |
||
401 | $clone->destroy(); |
||
402 | } |
||
403 | |||
404 | return $results; |
||
405 | } |
||
406 | |||
407 | private static function getBackgroundCanvas( |
||
408 | \Imagick $source, |
||
409 | string $color, |
||
410 | bool $blurBackground, |
||
411 | float $blurValue, |
||
412 | int $boxWidth, |
||
413 | int $boxHeight |
||
414 | ) : \Imagick { |
||
415 | if ($blurBackground || $color === 'blur') { |
||
416 | return self::getBlurredBackgroundCanvas($source, $blurValue, $boxWidth, $boxHeight); |
||
417 | } |
||
418 | |||
419 | return self::getColoredBackgroundCanvas($color, $boxWidth, $boxHeight); |
||
420 | } |
||
421 | |||
422 | private static function getColoredBackgroundCanvas(string $color, int $boxWidth, int $boxHeight) |
||
423 | { |
||
424 | $canvas = new \Imagick(); |
||
425 | $imageCreated = $canvas->newImage($boxWidth, $boxHeight, $color); |
||
426 | Util::ensure(true, $imageCreated, 'Imagick::newImage() did not return true'); |
||
427 | return $canvas; |
||
428 | } |
||
429 | |||
430 | private static function getBlurredBackgroundCanvas( |
||
431 | \Imagick $source, |
||
432 | float $blurValue, |
||
433 | int $boxWidth, |
||
434 | int $boxHeight |
||
435 | ) : \Imagick { |
||
436 | $canvas = clone $source; |
||
437 | self::rotateImage($canvas); |
||
438 | $canvas->resizeImage($boxWidth, $boxHeight, \Imagick::FILTER_BOX, $blurValue, false); |
||
439 | return $canvas; |
||
440 | } |
||
441 | |||
442 | /** |
||
443 | * write $source to $destPath with $options applied |
||
444 | * |
||
445 | * @param \Imagick $source source image. Will not modify |
||
446 | * @param string $destPath destination image path |
||
447 | * @param array $options options |
||
448 | * string format (default jpeg) Any from http://www.imagemagick.org/script/formats.php#supported |
||
449 | * int directoryMode (default 0777) chmod mode for any parent directories created |
||
450 | * int fileMode (default 0777) chmod mode for the resized image file |
||
451 | * bool stripHeaders (default true) whether to strip headers (exif, etc). Is only reflected in $destPath, |
||
452 | * not returned clone |
||
453 | * |
||
454 | * @return void |
||
455 | * |
||
456 | * @throws InvalidArgumentException if $destPath was not a string |
||
457 | * @throws InvalidArgumentException if $options["format"] was not a string |
||
458 | * @throws InvalidArgumentException if $options["directoryMode"] was not an int |
||
459 | * @throws InvalidArgumentException if $options["fileMode"] was not an int |
||
460 | * @throws InvalidArgumentException if $options["stripHeaders"] was not a bool |
||
461 | * @throws \Exception |
||
462 | */ |
||
463 | public static function write(\Imagick $source, string $destPath, array $options = []) |
||
464 | { |
||
465 | $format = 'jpeg'; |
||
466 | if (array_key_exists('format', $options)) { |
||
467 | $format = $options['format']; |
||
468 | if (!is_string($format)) { |
||
469 | throw new InvalidArgumentException('$options["format"] was not a string'); |
||
470 | } |
||
471 | } |
||
472 | |||
473 | $directoryMode = 0777; |
||
474 | if (array_key_exists('directoryMode', $options)) { |
||
475 | $directoryMode = $options['directoryMode']; |
||
476 | if (!is_int($directoryMode)) { |
||
477 | throw new InvalidArgumentException('$options["directoryMode"] was not an int'); |
||
478 | } |
||
479 | } |
||
480 | |||
481 | $fileMode = 0777; |
||
482 | if (array_key_exists('fileMode', $options)) { |
||
483 | $fileMode = $options['fileMode']; |
||
484 | if (!is_int($fileMode)) { |
||
485 | throw new InvalidArgumentException('$options["fileMode"] was not an int'); |
||
486 | } |
||
487 | } |
||
488 | |||
489 | $stripHeaders = true; |
||
490 | if (array_key_exists('stripHeaders', $options)) { |
||
491 | $stripHeaders = $options['stripHeaders']; |
||
492 | if ($stripHeaders !== false && $stripHeaders !== true) { |
||
493 | throw new InvalidArgumentException('$options["stripHeaders"] was not a bool'); |
||
494 | } |
||
495 | } |
||
496 | |||
497 | $destDir = dirname($destPath); |
||
498 | if (!is_dir($destDir)) { |
||
499 | $oldUmask = umask(0); |
||
500 | if (!mkdir($destDir, $directoryMode, true)) { |
||
501 | //cumbersome to test |
||
502 | throw new \Exception('mkdir() returned false');//@codeCoverageIgnore |
||
503 | } |
||
504 | |||
505 | umask($oldUmask); |
||
506 | } |
||
507 | |||
508 | $clone = clone $source; |
||
509 | |||
510 | if ($clone->setImageFormat($format) !== true) { |
||
511 | //cumbersome to test |
||
512 | throw new \Exception('Imagick::setImageFormat() did not return true');//@codeCoverageIgnore |
||
513 | } |
||
514 | |||
515 | if ($stripHeaders && $clone->stripImage() !== true) { |
||
516 | //cumbersome to test |
||
517 | throw new \Exception('Imagick::stripImage() did not return true');//@codeCoverageIgnore |
||
518 | } |
||
519 | |||
520 | if ($clone->writeImage($destPath) !== true) { |
||
521 | //cumbersome to test |
||
522 | throw new \Exception('Imagick::writeImage() did not return true');//@codeCoverageIgnore |
||
523 | } |
||
524 | |||
525 | if (!chmod($destPath, $fileMode)) { |
||
526 | //cumbersome to test |
||
527 | throw new \Exception('chmod() returned false');//@codeCoverageIgnore |
||
528 | } |
||
529 | } |
||
530 | |||
531 | /** |
||
532 | * Strips the headers (exif, etc) from an image at the given path. |
||
533 | * |
||
534 | * @param string $path The image path. |
||
535 | * @return void |
||
536 | * @throws InvalidArgumentException if $path is not a string |
||
537 | * @throws \Exception if there is a failure stripping the headers |
||
538 | * @throws \Exception if there is a failure writing the image back to path |
||
539 | */ |
||
540 | public static function stripHeaders(string $path) |
||
541 | { |
||
542 | $imagick = new \Imagick($path); |
||
543 | if ($imagick->stripImage() !== true) { |
||
544 | //cumbersome to test |
||
545 | throw new \Exception('Imagick::stripImage() did not return true');//@codeCoverageIgnore |
||
546 | } |
||
547 | |||
548 | if ($imagick->writeImage($path) !== true) { |
||
549 | //cumbersome to test |
||
550 | throw new \Exception('Imagick::writeImage() did not return true');//@codeCoverageIgnore |
||
551 | } |
||
552 | } |
||
553 | |||
554 | /** |
||
555 | * @param \Imagick $imagick |
||
556 | */ |
||
557 | private static function rotateImage(\Imagick $imagick) |
||
558 | { |
||
559 | $orientation = $imagick->getImageOrientation(); |
||
560 | switch ($orientation) { |
||
561 | case \Imagick::ORIENTATION_BOTTOMRIGHT: |
||
562 | $imagick->rotateimage('#fff', 180); |
||
563 | $imagick->stripImage(); |
||
564 | break; |
||
565 | case \Imagick::ORIENTATION_RIGHTTOP: |
||
566 | $imagick->rotateimage('#fff', 90); |
||
567 | $imagick->stripImage(); |
||
568 | break; |
||
569 | case \Imagick::ORIENTATION_LEFTBOTTOM: |
||
570 | $imagick->rotateimage('#fff', -90); |
||
571 | $imagick->stripImage(); |
||
572 | break; |
||
573 | } |
||
574 | } |
||
575 | } |
||
576 |
This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.
Both the
$myVar
assignment in line 1 and the$higher
assignment in line 2 are dead. The first because$myVar
is never used and the second because$higher
is always overwritten for every possible time line.