Cheetah
Size.php
Go to the documentation of this file.
1 <?php
2 
3 namespace Intervention\Image;
4 
5 use \Closure;
6 
7 class Size
8 {
14  public $width;
15 
21  public $height;
22 
28  public $pivot;
29 
37  public function __construct($width = null, $height = null, Point $pivot = null)
38  {
39  $this->width = is_numeric($width) ? intval($width) : 1;
40  $this->height = is_numeric($height) ? intval($height) : 1;
41  $this->pivot = $pivot ? $pivot : new Point;
42  }
43 
50  public function set($width, $height)
51  {
52  $this->width = $width;
53  $this->height = $height;
54  }
55 
61  public function setPivot(Point $point)
62  {
63  $this->pivot = $point;
64  }
65 
71  public function getWidth()
72  {
73  return $this->width;
74  }
75 
81  public function getHeight()
82  {
83  return $this->height;
84  }
85 
91  public function getRatio()
92  {
93  return $this->width / $this->height;
94  }
95 
104  public function resize($width, $height, Closure $callback = null)
105  {
106  if (is_null($width) && is_null($height)) {
107  throw new \Intervention\Image\Exception\InvalidArgumentException(
108  "Width or height needs to be defined."
109  );
110  }
111 
112  // new size with dominant width
113  $dominant_w_size = clone $this;
114  $dominant_w_size->resizeHeight($height, $callback);
115  $dominant_w_size->resizeWidth($width, $callback);
116 
117  // new size with dominant height
118  $dominant_h_size = clone $this;
119  $dominant_h_size->resizeWidth($width, $callback);
120  $dominant_h_size->resizeHeight($height, $callback);
121 
122  // decide which size to use
123  if ($dominant_h_size->fitsInto(new self($width, $height))) {
124  $this->set($dominant_h_size->width, $dominant_h_size->height);
125  } else {
126  $this->set($dominant_w_size->width, $dominant_w_size->height);
127  }
128 
129  return $this;
130  }
131 
139  private function resizeWidth($width, Closure $callback = null)
140  {
141  $constraint = $this->getConstraint($callback);
142 
143  if ($constraint->isFixed(Constraint::UPSIZE)) {
144  $max_width = $constraint->getSize()->getWidth();
145  $max_height = $constraint->getSize()->getHeight();
146  }
147 
148  if (is_numeric($width)) {
149 
150  if ($constraint->isFixed(Constraint::UPSIZE)) {
151  $this->width = ($width > $max_width) ? $max_width : $width;
152  } else {
153  $this->width = $width;
154  }
155 
156  if ($constraint->isFixed(Constraint::ASPECTRATIO)) {
157  $h = intval(round($this->width / $constraint->getSize()->getRatio()));
158 
159  if ($constraint->isFixed(Constraint::UPSIZE)) {
160  $this->height = ($h > $max_height) ? $max_height : $h;
161  } else {
162  $this->height = $h;
163  }
164  }
165  }
166  }
167 
175  private function resizeHeight($height, Closure $callback = null)
176  {
177  $constraint = $this->getConstraint($callback);
178 
179  if ($constraint->isFixed(Constraint::UPSIZE)) {
180  $max_width = $constraint->getSize()->getWidth();
181  $max_height = $constraint->getSize()->getHeight();
182  }
183 
184  if (is_numeric($height)) {
185 
186  if ($constraint->isFixed(Constraint::UPSIZE)) {
187  $this->height = ($height > $max_height) ? $max_height : $height;
188  } else {
189  $this->height = $height;
190  }
191 
192  if ($constraint->isFixed(Constraint::ASPECTRATIO)) {
193  $w = intval(round($this->height * $constraint->getSize()->getRatio()));
194 
195  if ($constraint->isFixed(Constraint::UPSIZE)) {
196  $this->width = ($w > $max_width) ? $max_width : $w;
197  } else {
198  $this->width = $w;
199  }
200  }
201  }
202  }
203 
211  public function relativePosition(Size $size)
212  {
213  $x = $this->pivot->x - $size->pivot->x;
214  $y = $this->pivot->y - $size->pivot->y;
215 
216  return new Point($x, $y);
217  }
218 
225  public function fit(Size $size, $position = 'center')
226  {
227  // create size with auto height
228  $auto_height = clone $size;
229 
230  $auto_height->resize($this->width, null, function ($constraint) {
231  $constraint->aspectRatio();
232  });
233 
234  // decide which version to use
235  if ($auto_height->fitsInto($this)) {
236 
237  $size = $auto_height;
238 
239  } else {
240 
241  // create size with auto width
242  $auto_width = clone $size;
243 
244  $auto_width->resize(null, $this->height, function ($constraint) {
245  $constraint->aspectRatio();
246  });
247 
248  $size = $auto_width;
249  }
250 
251  $this->align($position);
252  $size->align($position);
253  $size->setPivot($this->relativePosition($size));
254 
255  return $size;
256  }
257 
264  public function fitsInto(Size $size)
265  {
266  return ($this->width <= $size->width) && ($this->height <= $size->height);
267  }
268 
278  public function align($position, $offset_x = 0, $offset_y = 0)
279  {
280  switch (strtolower($position)) {
281 
282  case 'top':
283  case 'top-center':
284  case 'top-middle':
285  case 'center-top':
286  case 'middle-top':
287  $x = intval($this->width / 2);
288  $y = 0 + $offset_y;
289  break;
290 
291  case 'top-right':
292  case 'right-top':
293  $x = $this->width - $offset_x;
294  $y = 0 + $offset_y;
295  break;
296 
297  case 'left':
298  case 'left-center':
299  case 'left-middle':
300  case 'center-left':
301  case 'middle-left':
302  $x = 0 + $offset_x;
303  $y = intval($this->height / 2);
304  break;
305 
306  case 'right':
307  case 'right-center':
308  case 'right-middle':
309  case 'center-right':
310  case 'middle-right':
311  $x = $this->width - $offset_x;
312  $y = intval($this->height / 2);
313  break;
314 
315  case 'bottom-left':
316  case 'left-bottom':
317  $x = 0 + $offset_x;
318  $y = $this->height - $offset_y;
319  break;
320 
321  case 'bottom':
322  case 'bottom-center':
323  case 'bottom-middle':
324  case 'center-bottom':
325  case 'middle-bottom':
326  $x = intval($this->width / 2);
327  $y = $this->height - $offset_y;
328  break;
329 
330  case 'bottom-right':
331  case 'right-bottom':
332  $x = $this->width - $offset_x;
333  $y = $this->height - $offset_y;
334  break;
335 
336  case 'center':
337  case 'middle':
338  case 'center-center':
339  case 'middle-middle':
340  $x = intval($this->width / 2);
341  $y = intval($this->height / 2);
342  break;
343 
344  default:
345  case 'top-left':
346  case 'left-top':
347  $x = 0 + $offset_x;
348  $y = 0 + $offset_y;
349  break;
350  }
351 
352  $this->pivot->setPosition($x, $y);
353 
354  return $this;
355  }
356 
363  private function getConstraint(Closure $callback = null)
364  {
365  $constraint = new Constraint(clone $this);
366 
367  if (is_callable($callback)) {
368  $callback($constraint);
369  }
370 
371  return $constraint;
372  }
373 }
Intervention\Image\Constraint
Definition: Constraint.php:6
Intervention\Image\Size\align
align($position, $offset_x=0, $offset_y=0)
Definition: Size.php:278
Intervention\Image\Size\setPivot
setPivot(Point $point)
Definition: Size.php:61
Intervention\Image\Point
Definition: Point.php:6
php
Intervention\Image\Size\getRatio
getRatio()
Definition: Size.php:91
Intervention\Image\Size\relativePosition
relativePosition(Size $size)
Definition: Size.php:211
Intervention\Image\Size\getHeight
getHeight()
Definition: Size.php:81
Intervention\Image\Size\getWidth
getWidth()
Definition: Size.php:71
Intervention\Image\Size\$pivot
$pivot
Definition: Size.php:28
Intervention\Image\Size\resize
resize($width, $height, Closure $callback=null)
Definition: Size.php:104
Intervention\Image\Size\fit
fit(Size $size, $position='center')
Definition: Size.php:225
Intervention\Image\Constraint\ASPECTRATIO
const ASPECTRATIO
Definition: Constraint.php:10
Intervention\Image\Constraint\UPSIZE
const UPSIZE
Definition: Constraint.php:15
Intervention\Image\Size\$width
$width
Definition: Size.php:14
Intervention\Image\Size\__construct
__construct($width=null, $height=null, Point $pivot=null)
Definition: Size.php:37
Intervention\Image\Size\fitsInto
fitsInto(Size $size)
Definition: Size.php:264
Intervention\Image\Size\$height
$height
Definition: Size.php:21
Intervention\Image\Size
Definition: Size.php:8
Intervention\Image
Definition: AbstractColor.php:3