Elgg  Version 2.3
ImageService.php
Go to the documentation of this file.
1 <?php
2 
3 namespace Elgg;
4 
10 
17 class ImageService {
18 
19  const JPEG_QUALITY = 75;
20 
24  private $imagine;
25 
29  private $config;
30 
37  public function __construct(ImagineInterface $imagine, Config $config) {
38  $this->imagine = $imagine;
39  $this->config = $config;
40  }
41 
66  public function resize($source, $destination = null, array $params = []) {
67 
68  if (!isset($destination)) {
69  $destination = $source;
70  }
71 
72  try {
73  $image = $this->imagine->open($source);
74 
75  $width = $image->getSize()->getWidth();
76  $height = $image->getSize()->getHeight();
77 
78  $resize_params = $this->normalizeResizeParameters($width, $height, $params);
79 
80  $max_width = elgg_extract('w', $resize_params);
81  $max_height = elgg_extract('h', $resize_params);
82 
83  $x1 = (int) elgg_extract('x1', $resize_params, 0);
84  $y1 = (int) elgg_extract('y1', $resize_params, 0);
85  $x2 = (int) elgg_extract('x2', $resize_params, 0);
86  $y2 = (int) elgg_extract('y2', $resize_params, 0);
87 
88  if ($x2 > $x1 && $y2 > $y1) {
89  $crop_start = new Point($x1, $y1);
90  $crop_size = new Box($x2 - $x1, $y2 - $y1);
91  $image->crop($crop_start, $crop_size);
92  }
93 
94  $target_size = new Box($max_width, $max_height);
95  $thumbnail = $image->resize($target_size);
96 
97  $thumbnail->save($destination, [
98  'jpeg_quality' => elgg_extract('jpeg_quality', $params, self::JPEG_QUALITY),
99  'format' => $this->getFileFormat($source, $params),
100  ]);
101 
102  unset($image);
103  unset($thumbnail);
104  } catch (Exception $ex) {
105  _elgg_services()->logger->error($ex->getMessage());
106  return false;
107  }
108 
109  return true;
110  }
111 
127  public function normalizeResizeParameters($width, $height, array $params = []) {
128 
129  $max_width = (int) elgg_extract('w', $params, 100, false);
130  $max_height = (int) elgg_extract('h', $params, 100, false);
131  if (!$max_height || !$max_width) {
132  throw new \LogicException("Resize width and height parameters are required");
133  }
134 
135  $square = elgg_extract('square', $params, false);
136  $upscale = elgg_extract('upscale', $params, false);
137 
138  $x1 = (int) elgg_extract('x1', $params, 0);
139  $y1 = (int) elgg_extract('y1', $params, 0);
140  $x2 = (int) elgg_extract('x2', $params, 0);
141  $y2 = (int) elgg_extract('y2', $params, 0);
142 
143  $cropping_mode = $x1 || $y1 || $x2 || $y2;
144 
145  if ($cropping_mode) {
146  $crop_width = $x2 - $x1;
147  $crop_height = $y2 - $y1;
148  if ($crop_width <= 0 || $crop_height <= 0 || $crop_width > $width || $crop_height > $height) {
149  throw new \LogicException("Coordinates [$x1, $y1], [$x2, $y2] are invalid for image cropping");
150  }
151  } else {
152  // everything selected if no crop parameters
153  $crop_width = $width;
154  $crop_height = $height;
155  }
156 
157  // determine cropping offsets
158  if ($square) {
159  // asking for a square image back
160  // detect case where someone is passing crop parameters that are not for a square
161  if ($cropping_mode == true && $crop_width != $crop_height) {
162  throw new \LogicException("Coordinates [$x1, $y1], [$x2, $y2] are invalid for a squared image cropping");
163  }
164 
165  // size of the new square image
166  $max_width = $max_height = min($max_width, $max_height);
167 
168  // find largest square that fits within the selected region
169  $crop_width = $crop_height = min($crop_width, $crop_height);
170 
171  if (!$cropping_mode) {
172  // place square region in the center
173  $x1 = floor(($width - $crop_width) / 2);
174  $y1 = floor(($height - $crop_height) / 2);
175  }
176  } else {
177  // maintain aspect ratio of original image/crop
178  if ($crop_height / $max_height > $crop_width / $max_width) {
179  $max_width = floor($max_height * $crop_width / $crop_height);
180  } else {
181  $max_height = floor($max_width * $crop_height / $crop_width);
182  }
183  }
184 
185  if (!$upscale && ($crop_height < $max_height || $crop_width < $max_width)) {
186  // we cannot upscale and selected area is too small so we decrease size of returned image
187  $max_height = $crop_height;
188  $max_width = $crop_width;
189  }
190 
191  return [
192  'w' => $max_width,
193  'h' => $max_height,
194  'x1' => $x1,
195  'y1' => $y1,
196  'x2' => $x1 + $crop_width,
197  'y2' => $y1 + $crop_height,
198  'square' => $square,
199  'upscale' => $upscale,
200  ];
201  }
202 
212  protected function getFileFormat($filename, $params) {
213 
214  $accepted_formats = [
215  'image/jpeg' => 'jpeg',
216  'image/pjpeg' => 'jpeg',
217  'image/png' => 'png',
218  'image/x-png' => 'png',
219  'image/gif' => 'gif',
220  'image/vnd.wap.wbmp' => 'wbmp',
221  'image/x‑xbitmap' => 'xbm',
222  'image/x‑xbm' => 'xbm',
223  ];
224 
225  // was a valid output format supplied
226  $format = elgg_extract('format', $params);
227  if (in_array($format, $accepted_formats)) {
228  return $format;
229  }
230 
231  $mime_detector = new MimeTypeDetector();
232  $mime = $mime_detector->getType($filename);
233 
234  return elgg_extract($mime, $accepted_formats);
235  }
236 }
Access to configuration values.
Definition: Config.php:11
$params
Definition: login.php:72
Save menu items.
Image manipulation service.
_elgg_services(\Elgg\Di\ServiceProvider $services=null)
Get the global service provider.
Definition: autoloader.php:17
getFileFormat($filename, $params)
Determine the image file format, this is needed for correct resizing.
__construct(ImagineInterface $imagine, Config $config)
Constructor.
elgg_extract($key, $array, $default=null, $strict=true)
Checks for $array[$key] and returns its value if it exists, else returns $default.
Definition: elgglib.php:1375
$format
Detect the MIME type of a file.
resize($source, $destination=null, array $params=[])
Crop and resize an image.
$filename
http free of to any person obtaining a copy of this software and associated documentation to deal in the Software without including without limitation the rights to use
Definition: MIT-LICENSE.txt:5
normalizeResizeParameters($width, $height, array $params=[])
Calculate the parameters for resizing an image.
$image
Definition: upload.php:37