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 League\Glide\Manipulators; |
||
4 | |||
5 | use Intervention\Image\Image; |
||
6 | |||
7 | /** |
||
8 | * @property string $dpr |
||
9 | * @property string $fit |
||
10 | * @property string $h |
||
11 | * @property string $w |
||
12 | */ |
||
13 | class Size extends BaseManipulator |
||
14 | { |
||
15 | /** |
||
16 | * Maximum image size in pixels. |
||
17 | * @var int|null |
||
18 | */ |
||
19 | protected $maxImageSize; |
||
20 | |||
21 | /** |
||
22 | * Create Size instance. |
||
23 | * @param int|null $maxImageSize Maximum image size in pixels. |
||
24 | */ |
||
25 | 66 | public function __construct($maxImageSize = null) |
|
26 | { |
||
27 | 66 | $this->maxImageSize = $maxImageSize; |
|
28 | 66 | } |
|
29 | |||
30 | /** |
||
31 | * Set the maximum image size. |
||
32 | * @param int|null Maximum image size in pixels. |
||
33 | */ |
||
34 | 6 | public function setMaxImageSize($maxImageSize) |
|
35 | { |
||
36 | 6 | $this->maxImageSize = $maxImageSize; |
|
37 | 6 | } |
|
38 | |||
39 | /** |
||
40 | * Get the maximum image size. |
||
41 | * @return int|null Maximum image size in pixels. |
||
42 | */ |
||
43 | 6 | public function getMaxImageSize() |
|
44 | { |
||
45 | 6 | return $this->maxImageSize; |
|
46 | } |
||
47 | |||
48 | /** |
||
49 | * Perform size image manipulation. |
||
50 | * @param Image $image The source image. |
||
51 | * @return Image The manipulated image. |
||
52 | */ |
||
53 | 6 | public function run(Image $image) |
|
54 | { |
||
55 | 6 | $width = $this->getWidth(); |
|
56 | 6 | $height = $this->getHeight(); |
|
57 | 6 | $fit = $this->getFit(); |
|
58 | 6 | $dpr = $this->getDpr(); |
|
59 | |||
60 | 6 | list($width, $height) = $this->resolveMissingDimensions($image, $width, $height); |
|
61 | 6 | list($width, $height) = $this->applyDpr($width, $height, $dpr); |
|
62 | 6 | list($width, $height) = $this->limitImageSize($width, $height); |
|
63 | |||
64 | 6 | if ((int) $width !== (int) $image->width() or (int) $height !== (int) $image->height()) { |
|
65 | 6 | $image = $this->runResize($image, $fit, (int) $width, (int) $height); |
|
66 | 4 | } |
|
67 | |||
68 | 6 | return $image; |
|
69 | } |
||
70 | |||
71 | /** |
||
72 | * Resolve width. |
||
73 | * @return int The resolved width. |
||
74 | */ |
||
75 | 9 | public function getWidth() |
|
76 | { |
||
77 | 9 | if (!is_numeric($this->w)) { |
|
78 | 3 | return; |
|
79 | } |
||
80 | |||
81 | 9 | if ($this->w <= 0) { |
|
82 | 3 | return; |
|
83 | } |
||
84 | |||
85 | 9 | return (int) $this->w; |
|
86 | } |
||
87 | |||
88 | /** |
||
89 | * Resolve height. |
||
90 | * @return int The resolved height. |
||
91 | */ |
||
92 | 9 | public function getHeight() |
|
93 | { |
||
94 | 9 | if (!is_numeric($this->h)) { |
|
95 | 6 | return; |
|
96 | } |
||
97 | |||
98 | 6 | if ($this->h <= 0) { |
|
99 | 3 | return; |
|
100 | } |
||
101 | |||
102 | 6 | return (int) $this->h; |
|
103 | } |
||
104 | |||
105 | /** |
||
106 | * Resolve fit. |
||
107 | * @return string The resolved fit. |
||
108 | */ |
||
109 | 9 | public function getFit() |
|
110 | { |
||
111 | 9 | if (in_array($this->fit, ['contain', 'fill', 'max', 'stretch'], true)) { |
|
112 | 3 | return $this->fit; |
|
113 | } |
||
114 | |||
115 | 9 | if (preg_match('/^(crop)(-top-left|-top|-top-right|-left|-center|-right|-bottom-left|-bottom|-bottom-right|-[\d]{1,3}-[\d]{1,3})*$/', $this->fit)) { |
|
116 | 3 | return 'crop'; |
|
117 | } |
||
118 | |||
119 | 9 | return 'contain'; |
|
120 | } |
||
121 | |||
122 | /** |
||
123 | * Resolve crop. |
||
124 | * @return array The resolved crop. |
||
125 | */ |
||
126 | 9 | public function getCrop() |
|
127 | { |
||
128 | $cropMethods = [ |
||
129 | 9 | 'crop-top-left' => [0, 0], |
|
130 | 6 | 'crop-top' => [50, 0], |
|
131 | 6 | 'crop-top-right' => [100, 0], |
|
132 | 6 | 'crop-left' => [0, 50], |
|
133 | 6 | 'crop-center' => [50, 50], |
|
134 | 6 | 'crop-right' => [100, 50], |
|
135 | 6 | 'crop-bottom-left' => [0, 100], |
|
136 | 6 | 'crop-bottom' => [50, 100], |
|
137 | 6 | 'crop-bottom-right' => [100, 100], |
|
138 | 6 | ]; |
|
139 | |||
140 | 9 | if (array_key_exists($this->fit, $cropMethods)) { |
|
141 | 3 | return $cropMethods[$this->fit]; |
|
142 | } |
||
143 | |||
144 | 9 | if (preg_match('/^crop-([\d]{1,3})-([\d]{1,3})*$/', $this->fit, $matches)) { |
|
145 | 3 | if ($matches[1] > 100 or $matches[2] > 100) { |
|
146 | 3 | return [50, 50]; |
|
147 | } |
||
148 | |||
149 | 3 | return [(int) $matches[1], (int) $matches[2]]; |
|
150 | } |
||
151 | |||
152 | 9 | return [50, 50]; |
|
153 | } |
||
154 | |||
155 | /** |
||
156 | * Resolve the device pixel ratio. |
||
157 | * @return double The device pixel ratio. |
||
158 | */ |
||
159 | 9 | public function getDpr() |
|
160 | { |
||
161 | 9 | if (!is_numeric($this->dpr)) { |
|
162 | 9 | return 1.0; |
|
163 | } |
||
164 | |||
165 | 3 | if ($this->dpr < 0 or $this->dpr > 8) { |
|
166 | 3 | return 1.0; |
|
167 | } |
||
168 | |||
169 | 3 | return (double) $this->dpr; |
|
170 | } |
||
171 | |||
172 | /** |
||
173 | * Resolve missing image dimensions. |
||
174 | * @param Image $image The source image. |
||
175 | * @param int|null $width The image width. |
||
176 | * @param int|null $height The image height. |
||
177 | * @return int[] The resolved width and height. |
||
178 | */ |
||
179 | 9 | public function resolveMissingDimensions(Image $image, $width, $height) |
|
180 | { |
||
181 | 9 | if (!$width and !$height) { |
|
182 | 3 | $width = $image->width(); |
|
183 | 3 | $height = $image->height(); |
|
184 | 2 | } |
|
185 | |||
186 | 9 | if (!$width) { |
|
0 ignored issues
–
show
|
|||
187 | 3 | $width = $height * ($image->width() / $image->height()); |
|
188 | 2 | } |
|
189 | |||
190 | 9 | if (!$height) { |
|
191 | 6 | $height = $width / ($image->width() / $image->height()); |
|
192 | 4 | } |
|
193 | |||
194 | return [ |
||
195 | 9 | (int) $width, |
|
196 | 9 | (int) $height, |
|
197 | 6 | ]; |
|
198 | } |
||
199 | |||
200 | /** |
||
201 | * Apply the device pixel ratio. |
||
202 | * @param int $width The target image width. |
||
203 | * @param int $height The target image height. |
||
204 | * @param int $dpr The device pixel ratio. |
||
205 | * @return int[] The modified width and height. |
||
206 | */ |
||
207 | 6 | public function applyDpr($width, $height, $dpr) |
|
208 | { |
||
209 | 6 | $width = $width * $dpr; |
|
210 | 6 | $height = $height * $dpr; |
|
211 | |||
212 | return [ |
||
213 | 6 | (int) $width, |
|
214 | 6 | (int) $height, |
|
215 | 4 | ]; |
|
216 | } |
||
217 | |||
218 | /** |
||
219 | * Limit image size to maximum allowed image size. |
||
220 | * @param int $width The image width. |
||
221 | * @param int $height The image height. |
||
222 | * @return int[] The limited width and height. |
||
223 | */ |
||
224 | 9 | public function limitImageSize($width, $height) |
|
225 | { |
||
226 | 9 | if ($this->maxImageSize !== null) { |
|
227 | 3 | $imageSize = $width * $height; |
|
228 | |||
229 | 3 | if ($imageSize > $this->maxImageSize) { |
|
230 | 3 | $width = $width / sqrt($imageSize / $this->maxImageSize); |
|
231 | 3 | $height = $height / sqrt($imageSize / $this->maxImageSize); |
|
232 | 2 | } |
|
233 | 2 | } |
|
234 | |||
235 | return [ |
||
236 | 9 | (int) $width, |
|
237 | 9 | (int) $height, |
|
238 | 6 | ]; |
|
239 | } |
||
240 | |||
241 | /** |
||
242 | * Perform resize image manipulation. |
||
243 | * @param Image $image The source image. |
||
244 | * @param string $fit The fit. |
||
245 | * @param int $width The width. |
||
246 | * @param int $height The height. |
||
247 | * @return Image The manipulated image. |
||
248 | */ |
||
249 | 9 | public function runResize(Image $image, $fit, $width, $height) |
|
250 | { |
||
251 | 9 | if ($fit === 'contain') { |
|
252 | 9 | return $this->runContainResize($image, $width, $height); |
|
253 | } |
||
254 | |||
255 | 3 | if ($fit === 'fill') { |
|
256 | 3 | return $this->runFillResize($image, $width, $height); |
|
257 | } |
||
258 | |||
259 | 3 | if ($fit === 'max') { |
|
260 | 3 | return $this->runMaxResize($image, $width, $height); |
|
261 | } |
||
262 | |||
263 | 3 | if ($fit === 'stretch') { |
|
264 | 3 | return $this->runStretchResize($image, $width, $height); |
|
265 | } |
||
266 | |||
267 | 3 | if ($fit === 'crop') { |
|
268 | 3 | return $this->runCropResize($image, $width, $height); |
|
269 | } |
||
270 | |||
271 | 3 | return $image; |
|
272 | } |
||
273 | |||
274 | /** |
||
275 | * Perform contain resize image manipulation. |
||
276 | * @param Image $image The source image. |
||
277 | * @param int $width The width. |
||
278 | * @param int $height The height. |
||
279 | * @return Image The manipulated image. |
||
280 | */ |
||
281 | 12 | public function runContainResize(Image $image, $width, $height) |
|
282 | { |
||
283 | return $image->resize($width, $height, function ($constraint) { |
||
284 | $constraint->aspectRatio(); |
||
285 | 12 | }); |
|
286 | } |
||
287 | |||
288 | /** |
||
289 | * Perform max resize image manipulation. |
||
290 | * @param Image $image The source image. |
||
291 | * @param int $width The width. |
||
292 | * @param int $height The height. |
||
293 | * @return Image The manipulated image. |
||
294 | */ |
||
295 | 9 | public function runMaxResize(Image $image, $width, $height) |
|
296 | { |
||
297 | return $image->resize($width, $height, function ($constraint) { |
||
298 | $constraint->aspectRatio(); |
||
299 | $constraint->upsize(); |
||
300 | 9 | }); |
|
301 | } |
||
302 | |||
303 | /** |
||
304 | * Perform fill resize image manipulation. |
||
305 | * @param Image $image The source image. |
||
306 | * @param int $width The width. |
||
307 | * @param int $height The height. |
||
308 | * @return Image The manipulated image. |
||
309 | */ |
||
310 | 6 | public function runFillResize($image, $width, $height) |
|
311 | { |
||
312 | 6 | $image = $this->runMaxResize($image, $width, $height); |
|
313 | |||
314 | 6 | return $image->resizeCanvas($width, $height, 'center'); |
|
315 | } |
||
316 | |||
317 | /** |
||
318 | * Perform stretch resize image manipulation. |
||
319 | * @param Image $image The source image. |
||
320 | * @param int $width The width. |
||
321 | * @param int $height The height. |
||
322 | * @return Image The manipulated image. |
||
323 | */ |
||
324 | 6 | public function runStretchResize(Image $image, $width, $height) |
|
325 | { |
||
326 | 6 | return $image->resize($width, $height); |
|
327 | } |
||
328 | |||
329 | /** |
||
330 | * Perform crop resize image manipulation. |
||
331 | * @param Image $image The source image. |
||
332 | * @param int $width The width. |
||
333 | * @param int $height The height. |
||
334 | * @return Image The manipulated image. |
||
335 | */ |
||
336 | 6 | public function runCropResize(Image $image, $width, $height) |
|
337 | { |
||
338 | 6 | list($offset_percentage_x, $offset_percentage_y) = $this->getCrop(); |
|
339 | |||
340 | 6 | $resize_width = $width; |
|
341 | 6 | $resize_height = $width * ($image->height() / $image->width()); |
|
342 | |||
343 | 6 | if ($height > $resize_height) { |
|
344 | $resize_width = $height * ($image->width() / $image->height()); |
||
345 | $resize_height = $height; |
||
346 | } |
||
347 | |||
348 | 6 | $image->resize($resize_width, $resize_height, function ($constraint) { |
|
349 | $constraint->aspectRatio(); |
||
350 | 6 | }); |
|
351 | |||
352 | 6 | $offset_x = (int) (($image->width() * $offset_percentage_x / 100) - ($width / 2)); |
|
353 | 6 | $offset_y = (int) (($image->height() * $offset_percentage_y / 100) - ($height / 2)); |
|
354 | |||
355 | 6 | $max_offset_x = $image->width() - $width; |
|
356 | 6 | $max_offset_y = $image->height() - $height; |
|
357 | |||
358 | 6 | if ($offset_x < 0) { |
|
359 | $offset_x = 0; |
||
360 | } |
||
361 | |||
362 | 6 | if ($offset_y < 0) { |
|
363 | $offset_y = 0; |
||
364 | } |
||
365 | |||
366 | 6 | if ($offset_x > $max_offset_x) { |
|
367 | $offset_x = $max_offset_x; |
||
368 | } |
||
369 | |||
370 | 6 | if ($offset_y > $max_offset_y) { |
|
371 | $offset_y = $max_offset_y; |
||
372 | } |
||
373 | |||
374 | 6 | return $image->crop( |
|
375 | 4 | $width, |
|
376 | 4 | $height, |
|
377 | 4 | $offset_x, |
|
378 | $offset_y |
||
379 | 4 | ); |
|
380 | } |
||
381 | } |
||
382 |
In PHP, under loose comparison (like
==
, or!=
, orswitch
conditions), values of different types might be equal.For
integer
values, zero is a special case, in particular the following results might be unexpected: