Total Complexity | 151 |
Total Lines | 1277 |
Duplicated Lines | 0 % |
Changes | 0 |
Complex classes like Image_Transform often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use Image_Transform, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
83 | class Image_Transform |
||
84 | { |
||
85 | /** |
||
86 | * Name of the image file |
||
87 | * @var string |
||
88 | */ |
||
89 | public $image = ''; |
||
90 | /** |
||
91 | * Type of the image file (eg. jpg, gif png ...) |
||
92 | * @var string |
||
93 | */ |
||
94 | public $type = ''; |
||
95 | /** |
||
96 | * Original image width in x direction |
||
97 | * @var int |
||
98 | */ |
||
99 | public $img_x = ''; |
||
100 | /** |
||
101 | * Original image width in y direction |
||
102 | * @var int |
||
103 | */ |
||
104 | public $img_y = ''; |
||
105 | /** |
||
106 | * New image width in x direction |
||
107 | * @var int |
||
108 | */ |
||
109 | public $new_x = ''; |
||
110 | /** |
||
111 | * New image width in y direction |
||
112 | * @var int |
||
113 | */ |
||
114 | public $new_y = ''; |
||
115 | /** |
||
116 | * Path to the library used |
||
117 | * e.g. /usr/local/ImageMagick/bin/ or |
||
118 | * /usr/local/netpbm/ |
||
119 | */ |
||
120 | public $lib_path = ''; |
||
121 | /** |
||
122 | * Flag to warn if image has been resized more than once before displaying |
||
123 | * or saving. |
||
124 | */ |
||
125 | public $resized = false; |
||
126 | /** |
||
127 | * @var array General options |
||
128 | * @access protected |
||
129 | */ |
||
130 | public $_options = [ |
||
131 | 'quality' => 75, |
||
132 | 'scaleMethod' => 'smooth', |
||
133 | 'canvasColor' => [255, 255, 255], |
||
134 | 'pencilColor' => [0, 0, 0], |
||
135 | 'textColor' => [0, 0, 0], |
||
136 | ]; |
||
137 | /** |
||
138 | * Flag for whether settings should be discarded on saving/display of image |
||
139 | * @var bool |
||
140 | * @see Image_Transform::keepSettingsOnSave |
||
141 | */ |
||
142 | public $keep_settings_on_save = false; |
||
143 | /** |
||
144 | * Supported image types |
||
145 | * @var array |
||
146 | * @access protected |
||
147 | */ |
||
148 | public $_supported_image_types = []; |
||
149 | /** |
||
150 | * Initialization error tracking |
||
151 | * @var object |
||
152 | * @access private |
||
153 | **/ |
||
154 | public $_error = null; |
||
155 | /** |
||
156 | * associative array that tracks existence of programs |
||
157 | * (for drivers using shell interface and a tiny performance |
||
158 | * improvement if the clearstatcache() is used) |
||
159 | * @var array |
||
160 | * @access protected |
||
161 | */ |
||
162 | public $_programs = []; |
||
163 | /** |
||
164 | * Default parameters used in the addText methods. |
||
165 | */ |
||
166 | public $default_text_params = [ |
||
167 | 'text' => 'Default text', |
||
168 | 'x' => 10, |
||
169 | 'y' => 20, |
||
170 | 'color' => 'red', |
||
171 | 'font' => 'Arial.ttf', |
||
172 | 'size' => 12, |
||
173 | 'angle' => 0, |
||
174 | 'resize_first' => false, |
||
175 | ]; |
||
176 | |||
177 | /** |
||
178 | * Creates a new Image_Transform object |
||
179 | * |
||
180 | * @param string $driver name of driver class to initialize. If no driver |
||
181 | * is specified the factory will attempt to use 'Imagick' first |
||
182 | * then 'GD' second, then 'Imlib' last |
||
183 | * |
||
184 | * @return object an Image_Transform object, or PEAR_Error on error |
||
185 | * |
||
186 | * @see PEAR::isError() |
||
187 | * @see Image_Transform::setOption() |
||
188 | */ |
||
189 | public function &factory($driver = '') |
||
190 | { |
||
191 | if ('' == $driver) { |
||
192 | $extensions = [ |
||
193 | 'imagick' => 'Imagick3', |
||
194 | 'gd' => 'GD', |
||
195 | 'imlib' => 'Imlib', |
||
196 | ]; |
||
197 | if (version_compare(PHP_VERSION, '5.0.0', '<')) { |
||
198 | //Imagick2 driver for php < 5 |
||
199 | $extensions['imagick'] = 'Imagick2'; |
||
200 | } |
||
201 | |||
202 | foreach ($extensions as $ext => $ext_driver) { |
||
203 | if (PEAR::loadExtension($ext)) { |
||
204 | $driver = $ext_driver; |
||
205 | break; |
||
206 | } |
||
207 | } |
||
208 | if (!$driver) { |
||
209 | return PEAR::raiseError('No image library specified and none can be found.' . ' You must specify driver in factory() call.', IMAGE_TRANSFORM_ERROR_ARGUMENT); |
||
|
|||
210 | } |
||
211 | } else { |
||
212 | switch (mb_strtolower($driver)) { |
||
213 | case 'gd': |
||
214 | $driver = 'GD'; |
||
215 | break; |
||
216 | case 'imagick': |
||
217 | $driver = 'Imagick3'; |
||
218 | if (version_compare(PHP_VERSION, '5.0.0', '<')) { |
||
219 | $driver = 'Imagick2'; |
||
220 | } |
||
221 | break; |
||
222 | case 'imlib': |
||
223 | $driver = 'Imlib'; |
||
224 | break; |
||
225 | } |
||
226 | } |
||
227 | |||
228 | // $file = 'Image/Transform/Driver/' . $driver . '.php'; |
||
229 | $file = __DIR__ . '/Transform/Driver/' . $driver . '.php'; |
||
230 | if (!@fclose(@fopen($file, 'r', true))) { |
||
231 | return PEAR::raiseError('Driver failed to load file ' . $file, IMAGE_TRANSFORM_DRIVER_FILE_MISSING); |
||
232 | } |
||
233 | |||
234 | $classname = 'Image_Transform_Driver_' . $driver; |
||
235 | |||
236 | if (!class_exists($classname)) { |
||
237 | require_once $file; |
||
238 | |||
239 | if (!class_exists($classname)) { |
||
240 | return PEAR::raiseError('Image library ' . $driver . ' not supported... aborting.', IMAGE_TRANSFORM_ERROR_UNSUPPORTED); |
||
241 | } |
||
242 | } |
||
243 | $obj = new $classname(); |
||
244 | |||
245 | // Check startup error |
||
246 | $error = &$obj->isError(); |
||
247 | if ($error) { |
||
248 | $obj = &$error; |
||
249 | } |
||
250 | |||
251 | return $obj; |
||
252 | } |
||
253 | |||
254 | /** |
||
255 | * Returns/sets an error when the instance couldn't initialize properly |
||
256 | * |
||
257 | * @param object $error PEAR_Error object when setting an error |
||
258 | * |
||
259 | * @return mixed FALSE or PEAR_Error object |
||
260 | * @access protected |
||
261 | */ |
||
262 | public function &isError($error = null) |
||
263 | { |
||
264 | if (null !== $error) { |
||
265 | $this->_error = &$error; |
||
266 | } |
||
267 | |||
268 | return $this->_error; |
||
269 | } |
||
270 | |||
271 | /** |
||
272 | * Resizes the image in the X and/or Y direction(s) |
||
273 | * |
||
274 | * If either is 0 it will keep the original size for that dimension |
||
275 | * |
||
276 | * @param mixed $new_x (0, number, percentage 10% or 0.1) |
||
277 | * @param mixed $new_y (0, number, percentage 10% or 0.1) |
||
278 | * @param array $options Options |
||
279 | * |
||
280 | * @return mixed TRUE or PEAR_Error object on error |
||
281 | * @access public |
||
282 | */ |
||
283 | public function resize($new_x = 0, $new_y = 0, $options = null) |
||
284 | { |
||
285 | // 0 means keep original size |
||
286 | $new_x = (0 == $new_x) ? $this->img_x : $this->_parse_size($new_x, $this->img_x); |
||
287 | $new_y = (0 == $new_y) ? $this->img_y : $this->_parse_size($new_y, $this->img_y); |
||
288 | |||
289 | // Now do the library specific resizing. |
||
290 | return $this->_resize($new_x, $new_y, $options); |
||
291 | } |
||
292 | |||
293 | // End resize |
||
294 | |||
295 | /** |
||
296 | * Scales the image to the specified width |
||
297 | * |
||
298 | * This method preserves the aspect ratio |
||
299 | * |
||
300 | * @param int $new_x Size to scale X-dimension to |
||
301 | * |
||
302 | * @return mixed TRUE or PEAR_Error object on error |
||
303 | * @access public |
||
304 | */ |
||
305 | public function scaleByX($new_x) |
||
306 | { |
||
307 | if ($new_x <= 0) { |
||
308 | return PEAR::raiseError('New size must be strictly positive', IMAGE_TRANSFORM_ERROR_OUTOFBOUND); |
||
309 | } |
||
310 | $new_y = round(($new_x / $this->img_x) * $this->img_y, 0); |
||
311 | |||
312 | return $this->_resize(max(1, $new_x), max(1, $new_y)); |
||
313 | } |
||
314 | |||
315 | // End scaleByX |
||
316 | |||
317 | /** |
||
318 | * Alias for resize() |
||
319 | * |
||
320 | * @param int $new_x |
||
321 | * @param int $new_y |
||
322 | * @param null $options |
||
323 | * @return mixed |
||
324 | * @see resize() |
||
325 | */ |
||
326 | public function scaleByXY($new_x = 0, $new_y = 0, $options = null) |
||
327 | { |
||
328 | return $this->resize($new_x, $new_y, $options); |
||
329 | } |
||
330 | |||
331 | // End scaleByXY |
||
332 | |||
333 | /** |
||
334 | * Scales the image to the specified height. |
||
335 | * |
||
336 | * This method preserves the aspect ratio |
||
337 | * |
||
338 | * @param int $new_y Size to scale Y-dimension to |
||
339 | * |
||
340 | * @return mixed TRUE or PEAR_Error object on error |
||
341 | * @access public |
||
342 | */ |
||
343 | public function scaleByY($new_y) |
||
344 | { |
||
345 | if ($new_y <= 0) { |
||
346 | return PEAR::raiseError('New size must be strictly positive', IMAGE_TRANSFORM_ERROR_OUTOFBOUND); |
||
347 | } |
||
348 | $new_x = round(($new_y / $this->img_y) * $this->img_x, 0); |
||
349 | |||
350 | return $this->_resize(max(1, $new_x), max(1, $new_y)); |
||
351 | } |
||
352 | |||
353 | // End scaleByY |
||
354 | |||
355 | /** |
||
356 | * Scales an image by a percentage, factor or a given length |
||
357 | * |
||
358 | * This method preserves the aspect ratio |
||
359 | * |
||
360 | * @param mixed $size (number, percentage 10% or 0.1) |
||
361 | * |
||
362 | * @return mixed TRUE or PEAR_Error object on error |
||
363 | * @access public |
||
364 | * @see scaleByPercentage, scaleByFactor, scaleByLength |
||
365 | */ |
||
366 | public function scale($size) |
||
367 | { |
||
368 | if ((mb_strlen($size) > 1) && ('%' == mb_substr($size, -1))) { |
||
369 | return $this->scaleByPercentage(mb_substr($size, 0, -1)); |
||
370 | } elseif ($size < 1) { |
||
371 | return $this->scaleByFactor($size); |
||
372 | } |
||
373 | |||
374 | return $this->scaleByLength($size); |
||
375 | } |
||
376 | |||
377 | // End scale |
||
378 | |||
379 | /** |
||
380 | * Scales an image to a percentage of its original size. For example, if |
||
381 | * my image was 640x480 and I called scaleByPercentage(10) then the image |
||
382 | * would be resized to 64x48 |
||
383 | * |
||
384 | * @param int $size Percentage of original size to scale to |
||
385 | * |
||
386 | * @return mixed TRUE or PEAR_Error object on error |
||
387 | * @access public |
||
388 | */ |
||
389 | public function scaleByPercentage($size) |
||
390 | { |
||
391 | return $this->scaleByFactor($size / 100); |
||
392 | } |
||
393 | |||
394 | // End scaleByPercentage |
||
395 | |||
396 | /** |
||
397 | * Scales an image to a factor of its original size. For example, if |
||
398 | * my image was 640x480 and I called scaleByFactor(0.5) then the image |
||
399 | * would be resized to 320x240. |
||
400 | * |
||
401 | * @param float $size Factor of original size to scale to |
||
402 | * |
||
403 | * @return mixed TRUE or PEAR_Error object on error |
||
404 | * @access public |
||
405 | */ |
||
406 | public function scaleByFactor($size) |
||
407 | { |
||
408 | if ($size <= 0) { |
||
409 | return PEAR::raiseError('New size must be strictly positive', IMAGE_TRANSFORM_ERROR_OUTOFBOUND); |
||
410 | } |
||
411 | $new_x = round($size * $this->img_x, 0); |
||
412 | $new_y = round($size * $this->img_y, 0); |
||
413 | |||
414 | return $this->_resize(max(1, $new_x), max(1, $new_y)); |
||
415 | } |
||
416 | |||
417 | // End scaleByFactor |
||
418 | |||
419 | /** |
||
420 | * Scales an image so that the longest side has the specified dimension. |
||
421 | * |
||
422 | * This method preserves the aspect ratio |
||
423 | * |
||
424 | * @param int $size Max dimension in pixels |
||
425 | * |
||
426 | * @return mixed TRUE or PEAR_Error object on error |
||
427 | * @access public |
||
428 | */ |
||
429 | public function scaleMaxLength($size) |
||
430 | { |
||
431 | if ($size <= 0) { |
||
432 | return PEAR::raiseError('New size must be strictly positive', IMAGE_TRANSFORM_ERROR_OUTOFBOUND); |
||
433 | } |
||
434 | if ($this->img_x >= $this->img_y) { |
||
435 | $new_x = $size; |
||
436 | $new_y = round(($new_x / $this->img_x) * $this->img_y, 0); |
||
437 | } else { |
||
438 | $new_y = $size; |
||
439 | $new_x = round(($new_y / $this->img_y) * $this->img_x, 0); |
||
440 | } |
||
441 | |||
442 | return $this->_resize(max(1, $new_x), max(1, $new_y)); |
||
443 | } |
||
444 | |||
445 | // End scaleMaxLength |
||
446 | |||
447 | /** |
||
448 | * Alias for scaleMaxLength |
||
449 | * |
||
450 | * @param int $size Max dimension in pixels |
||
451 | * |
||
452 | * @return mixed TRUE or PEAR_Error object on error |
||
453 | * @access public |
||
454 | * @see scaleMaxLength() |
||
455 | */ |
||
456 | public function scaleByLength($size) |
||
457 | { |
||
458 | return $this->scaleMaxLength($size); |
||
459 | } |
||
460 | |||
461 | /** |
||
462 | * Fits the image in the specified box size |
||
463 | * |
||
464 | * If the image is bigger than the box specified by $width and $height, |
||
465 | * it will be scaled down to fit inside of it. |
||
466 | * If the image is smaller, nothing is done. |
||
467 | * |
||
468 | * @param int $width Width of the box in pixels |
||
469 | * @param int $height Height of the box in pixels |
||
470 | * |
||
471 | * @return bool|PEAR_Error TRUE or PEAR_Error object on error |
||
472 | * @access public |
||
473 | */ |
||
474 | public function fit($width, $height) |
||
475 | { |
||
476 | if ($width <= 0 || $height <= 0) { |
||
477 | return PEAR::raiseError('Invalid arguments.', IMAGE_TRANSFORM_ERROR_ARGUMENT); |
||
478 | } |
||
479 | $x = $this->img_x / $width; |
||
480 | $y = $this->img_y / $height; |
||
481 | if ($x <= 1 && $y <= 1) { |
||
482 | return true; |
||
483 | } elseif ($x > $y) { |
||
484 | return $this->scaleByX($width); |
||
485 | } |
||
486 | |||
487 | return $this->scaleByY($height); |
||
488 | } |
||
489 | |||
490 | /** |
||
491 | * This works as per fit, but creates the canvas of size $width x $height |
||
492 | * and positions the resized image on it, by default in the centre. |
||
493 | * |
||
494 | * @param unknown_type $width |
||
495 | * @param unknown_type $height |
||
496 | * @param string $posn |
||
497 | * |
||
498 | * @return unknown |
||
499 | */ |
||
500 | public function fitOnCanvas($width, $height, $posn = 'center') |
||
501 | { |
||
502 | return PEAR::raiseError('fitOnCanvas() method not supported by driver', IMAGE_TRANSFORM_ERROR_UNSUPPORTED); |
||
503 | } |
||
504 | |||
505 | /** |
||
506 | * Fits the image in the specified width |
||
507 | * |
||
508 | * If the image is wider than the width specified by $width, |
||
509 | * it will be scaled down to fit inside of it. |
||
510 | * If the image is smaller, nothing is done. |
||
511 | * |
||
512 | * @param int $width Maximum width in pixels |
||
513 | * |
||
514 | * @return bool|PEAR_Error TRUE or PEAR_Error object on error |
||
515 | * @access public |
||
516 | */ |
||
517 | public function fitX($width) |
||
518 | { |
||
519 | return ($this->img_x <= $width) ? true : $this->scaleByX($width); |
||
520 | } |
||
521 | |||
522 | /** |
||
523 | * Fits the image in the specified height |
||
524 | * |
||
525 | * If the image is taller than the height specified by $height, |
||
526 | * it will be scaled down to fit inside of it. |
||
527 | * If the image is smaller, nothing is done. |
||
528 | * |
||
529 | * @param int $height Maximum height in pixels |
||
530 | * |
||
531 | * @return bool|PEAR_Error TRUE or PEAR_Error object on error |
||
532 | * @access public |
||
533 | */ |
||
534 | public function fitY($height) |
||
535 | { |
||
536 | return ($this->img_y <= $height) ? true : $this->scaleByY($height); |
||
537 | } |
||
538 | |||
539 | /** |
||
540 | * Sets one options |
||
541 | * |
||
542 | * @param string $name Name of option |
||
543 | * @param mixed $value Value of option |
||
544 | * |
||
545 | * @access public |
||
546 | * @see setOptions() |
||
547 | */ |
||
548 | public function setOption($name, $value) |
||
549 | { |
||
550 | $this->_options[$name] = $value; |
||
551 | } |
||
552 | |||
553 | /** |
||
554 | * Sets multiple options at once |
||
555 | * |
||
556 | * Associative array of options: |
||
557 | * - quality (Integer: 0: poor - 100: best) |
||
558 | * - scaleMethod ('smooth', 'pixel') |
||
559 | * |
||
560 | * @param array $options Array of options |
||
561 | * |
||
562 | * @access public |
||
563 | */ |
||
564 | public function setOptions($options) |
||
565 | { |
||
566 | $this->_options = array_merge($this->_options, $options); |
||
567 | } |
||
568 | |||
569 | /** |
||
570 | * Sets the image type (in lowercase letters), the image height and width. |
||
571 | * |
||
572 | * @param string $image Image filename |
||
573 | * |
||
574 | * @return mixed TRUE or PEAR_error |
||
575 | * @access protected |
||
576 | * @see PHP_Compat::image_type_to_mime_type() |
||
577 | * @link http://php.net/getimagesize |
||
578 | */ |
||
579 | public function _get_image_details($image) |
||
580 | { |
||
581 | $data = @getimagesize($image); |
||
582 | // 1 = GIF, 2 = JPG, 3 = PNG, 4 = SWF, 5 = PSD, 6 = BMP, |
||
583 | // 7 = TIFF (intel byte order), 8 = TIFF (motorola byte order), |
||
584 | // 9 = JPC, 10 = JP2, 11 = JPX, 12 = JB2, 13 = SWC, 14 = IFF, |
||
585 | // 15 = WBMP, 16 = XBM |
||
586 | if (!is_array($data)) { |
||
587 | return PEAR::raiseError('Cannot fetch image or images details.', true); |
||
588 | } |
||
589 | |||
590 | switch ($data[2]) { |
||
591 | case IMAGETYPE_GIF: |
||
592 | $type = 'gif'; |
||
593 | break; |
||
594 | case IMAGETYPE_JPEG: |
||
595 | $type = 'jpeg'; |
||
596 | break; |
||
597 | case IMAGETYPE_PNG: |
||
598 | $type = 'png'; |
||
599 | break; |
||
600 | case IMAGETYPE_SWF: |
||
601 | $type = 'swf'; |
||
602 | break; |
||
603 | case IMAGETYPE_PSD: |
||
604 | $type = 'psd'; |
||
605 | break; |
||
606 | case IMAGETYPE_BMP: |
||
607 | $type = 'bmp'; |
||
608 | break; |
||
609 | case IMAGETYPE_TIFF_II: |
||
610 | case IMAGETYPE_TIFF_MM: |
||
611 | $type = 'tiff'; |
||
612 | break; |
||
613 | case IMAGETYPE_JPC: |
||
614 | $type = 'jpc'; |
||
615 | break; |
||
616 | case IMAGETYPE_JP2: |
||
617 | $type = 'jp2'; |
||
618 | break; |
||
619 | case IMAGETYPE_JPX: |
||
620 | $type = 'jpx'; |
||
621 | break; |
||
622 | case IMAGETYPE_JB2: |
||
623 | $type = 'jb2'; |
||
624 | break; |
||
625 | case IMAGETYPE_SWC: |
||
626 | $type = 'swc'; |
||
627 | break; |
||
628 | case IMAGETYPE_IFF: |
||
629 | $type = 'iff'; |
||
630 | break; |
||
631 | case IMAGETYPE_WBMP: |
||
632 | $type = 'wbmp'; |
||
633 | break; |
||
634 | case IMAGETYPE_XBM: |
||
635 | $type = 'xbm'; |
||
636 | break; |
||
637 | default: |
||
638 | return PEAR::raiseError('Cannot recognize image format', IMAGE_TRANSFORM_ERROR_UNSUPPORTED); |
||
639 | } |
||
640 | $this->img_x = $this->new_x = $data[0]; |
||
641 | $this->img_y = $this->new_y = $data[1]; |
||
642 | $this->type = $type; |
||
643 | |||
644 | return true; |
||
645 | } |
||
646 | |||
647 | /** |
||
648 | * Returns the matching IMAGETYPE_* constant for a given image type |
||
649 | * |
||
650 | * @param mixed $type String (GIF, JPG,...) |
||
651 | * |
||
652 | * @return mixed string or integer or input on error |
||
653 | * @access protected |
||
654 | * @see PHP_Compat::image_type_to_mime_type() |
||
655 | **/ |
||
656 | public function _convert_image_type($type) |
||
657 | { |
||
658 | switch (mb_strtolower($type)) { |
||
659 | case 'gif': |
||
660 | return IMAGETYPE_GIF; |
||
661 | case 'jpeg': |
||
662 | case 'jpg': |
||
663 | return IMAGETYPE_JPEG; |
||
664 | case 'png': |
||
665 | return IMAGETYPE_PNG; |
||
666 | case 'swf': |
||
667 | return IMAGETYPE_SWF; |
||
668 | case 'psd': |
||
669 | return IMAGETYPE_PSD; |
||
670 | case 'bmp': |
||
671 | return IMAGETYPE_BMP; |
||
672 | case 'tiff': |
||
673 | return IMAGETYPE_TIFF_II; |
||
674 | //IMAGETYPE_TIFF_MM; |
||
675 | case 'jpc': |
||
676 | return IMAGETYPE_JPC; |
||
677 | case 'jp2': |
||
678 | return IMAGETYPE_JP2; |
||
679 | case 'jpx': |
||
680 | return IMAGETYPE_JPX; |
||
681 | case 'jb2': |
||
682 | return IMAGETYPE_JB2; |
||
683 | case 'swc': |
||
684 | return IMAGETYPE_SWC; |
||
685 | case 'iff': |
||
686 | return IMAGETYPE_IFF; |
||
687 | case 'wbmp': |
||
688 | return IMAGETYPE_WBMP; |
||
689 | case 'xbm': |
||
690 | return IMAGETYPE_XBM; |
||
691 | default: |
||
692 | return $type; |
||
693 | } |
||
694 | |||
695 | return isset($types[$t = mb_strtolower($type)]) ? $types[$t] : $type; |
||
696 | } |
||
697 | |||
698 | /** |
||
699 | * Parses input for number format and convert |
||
700 | * |
||
701 | * If either parameter is 0 it will be scaled proportionally |
||
702 | * |
||
703 | * @param mixed $new_size (0, number, percentage 10% or 0.1) |
||
704 | * @param int $old_size |
||
705 | * |
||
706 | * @return mixed Integer or PEAR_error |
||
707 | * @access protected |
||
708 | */ |
||
709 | public function _parse_size($new_size, $old_size) |
||
710 | { |
||
711 | if ('%' == mb_substr($new_size, -1)) { |
||
712 | $new_size = mb_substr($new_size, 0, -1); |
||
713 | $new_size = $new_size / 100; |
||
714 | } |
||
715 | if ($new_size > 1) { |
||
716 | return (int)$new_size; |
||
717 | } elseif (0 == $new_size) { |
||
718 | return (int)$old_size; |
||
719 | } |
||
720 | |||
721 | return (int)round($new_size * $old_size, 0); |
||
722 | } |
||
723 | |||
724 | /** |
||
725 | * Returns an angle between 0 and 360 from any angle value |
||
726 | * |
||
727 | * @param float $angle The angle to normalize |
||
728 | * |
||
729 | * @return float the angle |
||
730 | * @access protected |
||
731 | */ |
||
732 | public function _rotation_angle($angle) |
||
733 | { |
||
734 | $angle %= 360; |
||
735 | |||
736 | return ($angle < 0) ? $angle + 360 : $angle; |
||
737 | } |
||
738 | |||
739 | /** |
||
740 | * Returns the current value of $this->default_text_params. |
||
741 | * |
||
742 | * @return array $this->default_text_params The current text parameters |
||
743 | * @access protected |
||
744 | */ |
||
745 | public function _get_default_text_params() |
||
746 | { |
||
747 | return $this->default_text_params; |
||
748 | } |
||
749 | |||
750 | /** |
||
751 | * Sets the image width |
||
752 | * |
||
753 | * @param int $size dimension to set |
||
754 | * |
||
755 | * @access protected |
||
756 | * @since 29/05/02 13:36:31 |
||
757 | */ |
||
758 | public function _set_img_x($size) |
||
759 | { |
||
760 | $this->img_x = $size; |
||
761 | } |
||
762 | |||
763 | /** |
||
764 | * Sets the image height |
||
765 | * |
||
766 | * @param int $size dimension to set |
||
767 | * |
||
768 | * @access protected |
||
769 | * @since 29/05/02 13:36:31 |
||
770 | */ |
||
771 | public function _set_img_y($size) |
||
772 | { |
||
773 | $this->img_y = $size; |
||
774 | } |
||
775 | |||
776 | /** |
||
777 | * Sets the new image width |
||
778 | * |
||
779 | * @param int $size dimension to set |
||
780 | * |
||
781 | * @access protected |
||
782 | * @since 29/05/02 13:36:31 |
||
783 | */ |
||
784 | public function _set_new_x($size) |
||
785 | { |
||
786 | $this->new_x = $size; |
||
787 | } |
||
788 | |||
789 | /** |
||
790 | * Sets the new image height |
||
791 | * |
||
792 | * @param int $size dimension to set |
||
793 | * |
||
794 | * @since 29/05/02 13:36:31 |
||
795 | * @access protected |
||
796 | */ |
||
797 | public function _set_new_y($size) |
||
798 | { |
||
799 | $this->new_y = $size; |
||
800 | } |
||
801 | |||
802 | /** |
||
803 | * Returns the image handle so that one can further try |
||
804 | * to manipulate the image |
||
805 | * |
||
806 | * @return object |
||
807 | * |
||
808 | * @access public |
||
809 | */ |
||
810 | public function getHandle() |
||
811 | { |
||
812 | return PEAR::raiseError('getHandle() method not supported by driver', IMAGE_TRANSFORM_ERROR_UNSUPPORTED); |
||
813 | } |
||
814 | |||
815 | //function getHandle() |
||
816 | |||
817 | /** |
||
818 | * Returns the type of the image being manipulated |
||
819 | * |
||
820 | * @return string the image type |
||
821 | * @access public |
||
822 | */ |
||
823 | public function getImageType() |
||
824 | { |
||
825 | return $this->type; |
||
826 | } |
||
827 | |||
828 | /** |
||
829 | * Returns the MIME type of the image being manipulated |
||
830 | * |
||
831 | * @param string $type Image type to get MIME type for |
||
832 | * |
||
833 | * @return string The MIME type if available, or an empty string |
||
834 | * @access public |
||
835 | * @see PHP_Compat::image_type_to_mime_type() |
||
836 | * @link http://php.net/image_type_to_mime_type |
||
837 | */ |
||
838 | public function getMimeType($type = null) |
||
839 | { |
||
840 | return image_type_to_mime_type($this->_convert_image_type($type ?: $this->type)); |
||
841 | } |
||
842 | |||
843 | /** |
||
844 | * Returns the new image width |
||
845 | * |
||
846 | * This function returns the width |
||
847 | * of the new image. |
||
848 | * |
||
849 | * @access public |
||
850 | * @return int The width of the new image. |
||
851 | */ |
||
852 | public function getNewImageWidth() |
||
853 | { |
||
854 | if (isset($this->new_x)) { |
||
855 | return (int)$this->new_x; |
||
856 | } |
||
857 | |||
858 | return false; |
||
859 | } |
||
860 | |||
861 | /** |
||
862 | * Return new image Y |
||
863 | * |
||
864 | * This function will retrieve the |
||
865 | * new image 'Y' and return it's value |
||
866 | * if it's set. |
||
867 | * |
||
868 | * @access public |
||
869 | * @return int The new height of the image. |
||
870 | */ |
||
871 | public function getNewImageHeight() |
||
872 | { |
||
873 | if (isset($this->new_y)) { |
||
874 | return (int)$this->new_y; |
||
875 | } |
||
876 | |||
877 | return false; |
||
878 | } |
||
879 | |||
880 | /** |
||
881 | * Returns the image width |
||
882 | * |
||
883 | * @return int the width of the image |
||
884 | * @access public |
||
885 | */ |
||
886 | public function getImageWidth() |
||
887 | { |
||
888 | return $this->img_x; |
||
889 | } |
||
890 | |||
891 | /** |
||
892 | * Returns the image height |
||
893 | * |
||
894 | * @return int the width of the image |
||
895 | * @access public |
||
896 | */ |
||
897 | public function getImageHeight() |
||
898 | { |
||
899 | return $this->img_y; |
||
900 | } |
||
901 | |||
902 | /** |
||
903 | * Returns the image size and extra format information |
||
904 | * |
||
905 | * @return array The width and height of the image |
||
906 | * @access public |
||
907 | * @see PHP::getimagesize() |
||
908 | */ |
||
909 | public function getImageSize() |
||
910 | { |
||
911 | return [ |
||
912 | $this->img_x, |
||
913 | $this->img_y, |
||
914 | $this->_convert_image_type($this->type), |
||
915 | 'height="' . $this->img_y . '" width="' . $this->img_x . '"', |
||
916 | 'mime' => $this->getMimeType(), |
||
917 | ]; |
||
918 | } |
||
919 | |||
920 | /** |
||
921 | * This looks at the current image type and attempts to determine which |
||
922 | * web-safe format will be most suited. It does not work brilliantly with |
||
923 | * *.png images, because it is very difficult to know whether they are |
||
924 | * 8-bit or greater. Guess I need to have fatter code here :-) |
||
925 | * |
||
926 | * @return string web-safe image type |
||
927 | * @access public |
||
928 | */ |
||
929 | public function getWebSafeFormat() |
||
930 | { |
||
931 | switch ($this->type) { |
||
932 | case 'gif': |
||
933 | case 'png': |
||
934 | return 'png'; |
||
935 | break; |
||
936 | default: |
||
937 | return 'jpeg'; |
||
938 | } // switch |
||
939 | } |
||
940 | |||
941 | /** |
||
942 | * Handles space in path and Windows/UNIX difference |
||
943 | * |
||
944 | * @param string $path Base dir |
||
945 | * @param string $command Command to execute |
||
946 | * @param string $args Arguments to pass to the command |
||
947 | * |
||
948 | * @return string A prepared string suitable for exec() |
||
949 | * @access protected |
||
950 | */ |
||
951 | public function _prepare_cmd($path, $command, $args = '') |
||
952 | { |
||
953 | if (!OS_WINDOWS |
||
954 | || !preg_match('/\s/', $path)) { |
||
955 | return $path . $command . ' ' . $args; |
||
956 | } |
||
957 | |||
958 | return 'start /D "' . $path . '" /B ' . $command . ' ' . $args; |
||
959 | } |
||
960 | |||
961 | /** |
||
962 | * Place holder for the real resize method |
||
963 | * used by extended methods to do the resizing |
||
964 | * |
||
965 | * @return PEAR_error |
||
966 | * @access protected |
||
967 | */ |
||
968 | public function _resize() |
||
971 | } |
||
972 | |||
973 | /** |
||
974 | * Normalizes the colors, gamma and other properties of an image |
||
975 | * (this should give a result equivalent to a Photoshop autolevels) |
||
976 | * |
||
977 | * @return PEAR_error |
||
978 | * @access public |
||
979 | */ |
||
980 | public function normalize() |
||
981 | { |
||
982 | return PEAR::raiseError('Normalize method not supported by driver', IMAGE_TRANSFORM_ERROR_UNSUPPORTED); |
||
983 | } |
||
984 | |||
985 | /** |
||
986 | * Loads an image file to work with |
||
987 | * |
||
988 | * Place holder for the real load method |
||
989 | * used by extended methods to do the resizing |
||
990 | * |
||
991 | * @param string $filename Full name of file |
||
992 | * |
||
993 | * @return PEAR_error |
||
994 | * @access public |
||
995 | */ |
||
996 | public function load($filename) |
||
997 | { |
||
998 | return PEAR::raiseError('load() method not supported by driver', IMAGE_TRANSFORM_ERROR_UNSUPPORTED); |
||
999 | } |
||
1000 | |||
1001 | /** |
||
1002 | * Outputs the image to standard output |
||
1003 | * |
||
1004 | * Place holder for the real display method |
||
1005 | * used by extended methods to do the resizing |
||
1006 | * |
||
1007 | * @param string $type Format of image to save as |
||
1008 | * @param mixed $quality Format-dependent |
||
1009 | * |
||
1010 | * @return PEAR_error |
||
1011 | * @access public |
||
1012 | */ |
||
1013 | public function display($type, $quality = null) |
||
1014 | { |
||
1015 | return PEAR::raiseError('display() method not supported by driver', IMAGE_TRANSFORM_ERROR_UNSUPPORTED); |
||
1016 | } |
||
1017 | |||
1018 | /** |
||
1019 | * Returns if the driver supports a given image type |
||
1020 | * |
||
1021 | * @param string $type Image type (GIF, PNG, JPEG...) |
||
1022 | * @param string $mode 'r' for read, 'w' for write, 'rw' for both |
||
1023 | * |
||
1024 | * @return true if type (and mode) is supported FALSE otherwise |
||
1025 | * @access public |
||
1026 | */ |
||
1027 | public function supportsType($type, $mode = 'rw') |
||
1028 | { |
||
1029 | return (false === mb_strpos(@$this->_supported_image_types[mb_strtolower($type)], $mode)) ? false : true; |
||
1030 | } |
||
1031 | |||
1032 | /** |
||
1033 | * Saves image to file |
||
1034 | * |
||
1035 | * Place holder for the real save method |
||
1036 | * used by extended methods to do the resizing |
||
1037 | * |
||
1038 | * @param string $filename Filename to save image to |
||
1039 | * @param string $type Format of image to save as |
||
1040 | * @param mixed $quality Format-dependent |
||
1041 | * |
||
1042 | * @return PEAR_error |
||
1043 | * @access public |
||
1044 | */ |
||
1045 | public function save($filename, $type, $quality = null) |
||
1046 | { |
||
1047 | return PEAR::raiseError('save() method not supported by driver', IMAGE_TRANSFORM_ERROR_UNSUPPORTED); |
||
1048 | } |
||
1049 | |||
1050 | /** |
||
1051 | * Releases resource |
||
1052 | * |
||
1053 | * Place holder for the real free method |
||
1054 | * used by extended methods to do the resizing |
||
1055 | * |
||
1056 | * @return PEAR_error |
||
1057 | * @access public |
||
1058 | */ |
||
1059 | public function free() |
||
1062 | } |
||
1063 | |||
1064 | /** |
||
1065 | * Converts a color string into an array of RGB values |
||
1066 | * |
||
1067 | * @param string $colorhex A color following the #FFFFFF format |
||
1068 | * |
||
1069 | * @return array 3-element array with 0-255 values |
||
1070 | * @access public |
||
1071 | * |
||
1072 | * @see rgb2colorname |
||
1073 | * @see colorarray2colorhex |
||
1074 | */ |
||
1075 | public function colorhex2colorarray($colorhex) |
||
1082 | } |
||
1083 | |||
1084 | /** |
||
1085 | * @param $type |
||
1086 | */ |
||
1087 | public function _send_display_headers($type) |
||
1088 | { |
||
1089 | // Find the filename of the original image: |
||
1090 | $filename = explode('.', basename($this->image)); |
||
1091 | $filename = $filename[0]; |
||
1092 | header('Content-type: ' . $this->getMimeType($type)); |
||
1093 | header('Content-Disposition: inline; filename=' . $filename . '.' . $type); |
||
1094 | } |
||
1095 | |||
1096 | /** |
||
1097 | * Converts an array of RGB value into a #FFFFFF format color. |
||
1098 | * |
||
1099 | * @param array $color 3-element array with 0-255 values |
||
1100 | * |
||
1101 | * @return mixed A color following the #FFFFFF format or FALSE |
||
1102 | * if the array couldn't be converted |
||
1103 | * @access public |
||
1104 | * |
||
1105 | * @see rgb2colorname |
||
1106 | * @see colorhex2colorarray |
||
1107 | */ |
||
1108 | public function colorarray2colorhex($color) |
||
1109 | { |
||
1110 | if (!is_array($color)) { |
||
1111 | return false; |
||
1112 | } |
||
1113 | $color = sprintf('#%02X%02X%02X', @$color[0], @$color[1], @$color[2]); |
||
1114 | |||
1115 | return (7 != mb_strlen($color)) ? false : $color; |
||
1116 | } |
||
1117 | |||
1118 | /** |
||
1119 | * Returns the temp directory according to either the TMP, TMPDIR, or TEMP env |
||
1120 | * variables. If these are not set it will also check for the existence of |
||
1121 | * /tmp, %WINDIR%\temp |
||
1122 | * |
||
1123 | * @access public |
||
1124 | * @return string The system tmp directory |
||
1125 | */ |
||
1126 | public function getTempDir() |
||
1127 | { |
||
1128 | require_once __DIR__ . '/System.php'; |
||
1129 | |||
1130 | return System::tmpdir(); |
||
1131 | } |
||
1132 | |||
1133 | /** |
||
1134 | * Returns a temporary filename using tempnam() and the above getTmpDir() function. |
||
1135 | * |
||
1136 | * @param string $dirname Optional directory name for the tmp file |
||
1137 | * |
||
1138 | * @return string Filename and path of the tmp file |
||
1139 | * @access public |
||
1140 | */ |
||
1141 | public function getTempFile($dirname = null) |
||
1142 | { |
||
1143 | if (null === $dirname) { |
||
1144 | require_once __DIR__ . '/System.php'; |
||
1145 | $dirname = System::tmpdir(); |
||
1146 | } |
||
1147 | |||
1148 | return tempnam($dirname, 'temp.'); |
||
1149 | } |
||
1150 | |||
1151 | /** |
||
1152 | * @param $bool |
||
1153 | */ |
||
1154 | public function keepSettingsOnSave($bool) |
||
1155 | { |
||
1156 | $this->keep_settings_on_save = $bool; |
||
1157 | } |
||
1158 | |||
1159 | /** |
||
1160 | * Methods to add to the driver classes in the future |
||
1161 | * |
||
1162 | * @return object |
||
1163 | */ |
||
1164 | public function addText() |
||
1165 | { |
||
1166 | return PEAR::raiseError('addText() method not supported by driver', IMAGE_TRANSFORM_ERROR_UNSUPPORTED); |
||
1167 | } |
||
1168 | |||
1169 | /** |
||
1170 | * @return object |
||
1171 | */ |
||
1172 | public function addDropShadow() |
||
1173 | { |
||
1174 | return PEAR::raiseError('addDropShadow() method not supported by driver', IMAGE_TRANSFORM_ERROR_UNSUPPORTED); |
||
1175 | } |
||
1176 | |||
1177 | /** |
||
1178 | * @return object |
||
1179 | */ |
||
1180 | public function addBorder() |
||
1183 | } |
||
1184 | |||
1185 | /** |
||
1186 | * Crops an image |
||
1187 | * |
||
1188 | * @param int $width Cropped image width |
||
1189 | * @param int $height Cropped image height |
||
1190 | * @param int $x X-coordinate to crop at |
||
1191 | * @param int $y Y-coordinate to crop at |
||
1192 | * |
||
1193 | * @return mixed TRUE or a PEAR_Error object on error |
||
1194 | * @access public |
||
1195 | **/ |
||
1196 | public function crop($width, $height, $x = 0, $y = 0) |
||
1199 | } |
||
1200 | |||
1201 | /** |
||
1202 | * @return object |
||
1203 | */ |
||
1204 | public function canvasResize() |
||
1205 | { |
||
1206 | return PEAR::raiseError('canvasResize() method not supported by driver', IMAGE_TRANSFORM_ERROR_UNSUPPORTED); |
||
1207 | } |
||
1208 | |||
1209 | /** |
||
1210 | * Corrects the gamma of an image |
||
1211 | * |
||
1212 | * @param float $outputgamma Gamma correction factor |
||
1213 | * |
||
1214 | * @return mixed TRUE or a PEAR_error object on error |
||
1215 | * @access public |
||
1216 | **/ |
||
1217 | public function gamma($outputgamma = 1.0) |
||
1218 | { |
||
1219 | return PEAR::raiseError('gamma() method not supported by driver', IMAGE_TRANSFORM_ERROR_UNSUPPORTED); |
||
1220 | } |
||
1221 | |||
1222 | /** |
||
1223 | * Rotates the image clockwise |
||
1224 | * |
||
1225 | * @param float $angle Angle of rotation in degres |
||
1226 | * @param mixed $options Rotation options |
||
1227 | * |
||
1228 | * @return bool|PEAR_Error TRUE on success, PEAR_Error object on error |
||
1229 | * @access public |
||
1230 | */ |
||
1231 | public function rotate($angle, $options = null) |
||
1232 | { |
||
1233 | return PEAR::raiseError('rotate() method not supported by driver', IMAGE_TRANSFORM_ERROR_UNSUPPORTED); |
||
1234 | } |
||
1235 | |||
1236 | /** |
||
1237 | * Horizontal mirroring |
||
1238 | * |
||
1239 | * @return mixed TRUE or PEAR_Error object on error |
||
1240 | * @access public |
||
1241 | * @see flip() |
||
1242 | **/ |
||
1243 | public function mirror() |
||
1244 | { |
||
1245 | return PEAR::raiseError('mirror() method not supported by driver', IMAGE_TRANSFORM_ERROR_UNSUPPORTED); |
||
1246 | } |
||
1247 | |||
1248 | /** |
||
1249 | * Vertical mirroring |
||
1250 | * |
||
1251 | * @return object or PEAR Error object on error |
||
1252 | * @access public |
||
1253 | * @see mirror() |
||
1254 | */ |
||
1255 | public function flip() |
||
1256 | { |
||
1257 | return PEAR::raiseError('flip() method not supported by driver', IMAGE_TRANSFORM_ERROR_UNSUPPORTED); |
||
1258 | } |
||
1259 | |||
1260 | /** |
||
1261 | * Converts an image into greyscale colors |
||
1262 | * |
||
1263 | * @return mixed TRUE or a PEAR error object on error |
||
1264 | * @access public |
||
1265 | **/ |
||
1266 | public function greyscale() |
||
1267 | { |
||
1268 | return PEAR::raiseError('greyscale() method not supported by driver', IMAGE_TRANSFORM_ERROR_UNSUPPORTED); |
||
1269 | } |
||
1270 | |||
1271 | /** |
||
1272 | * Converts an image into greyscale colors |
||
1273 | * |
||
1274 | * @return mixed TRUE or a PEAR error object on error |
||
1275 | * @see greyscale() |
||
1276 | **/ |
||
1277 | public function grayscale() |
||
1278 | { |
||
1279 | return $this->greyscale(); |
||
1280 | } |
||
1281 | |||
1282 | /** |
||
1283 | * Returns a color option |
||
1284 | * |
||
1285 | * @param string $colorOf one of 'canvasColor', 'pencilColor', 'fontColor' |
||
1286 | * @param array $options configuration options |
||
1287 | * @param array $default default value to return if color not found |
||
1288 | * |
||
1289 | * @return array an RGB color array |
||
1290 | * @access protected |
||
1291 | */ |
||
1292 | public function _getColor($colorOf, $options = [], $default = [0, 0, 0]) |
||
1293 | { |
||
1294 | $opt = array_merge($this->_options, (array)$options); |
||
1295 | if (isset($opt[$colorOf])) { |
||
1296 | $color = $opt[$colorOf]; |
||
1297 | if (is_array($color)) { |
||
1298 | return $color; |
||
1299 | } |
||
1300 | if ('#' == $color[0]) { |
||
1301 | return $this->colorhex2colorarray($color); |
||
1302 | } |
||
1303 | static $colornames = []; |
||
1304 | require_once __DIR__ . '/Image/Transform/Driver/ColorsDefs.php'; |
||
1305 | |||
1306 | return $colornames[$color] ?? $default; |
||
1307 | } |
||
1308 | |||
1309 | return $default; |
||
1310 | } |
||
1311 | |||
1312 | /** |
||
1313 | * Returns an option |
||
1314 | * |
||
1315 | * @param string $name name of option |
||
1316 | * @param array $options local override option array |
||
1317 | * @param mixed $default default value to return if option is not found |
||
1318 | * |
||
1319 | * @return mixed the option |
||
1320 | * @access protected |
||
1321 | */ |
||
1322 | public function _getOption($name, $options = [], $default = null) |
||
1323 | { |
||
1324 | $opt = array_merge($this->_options, (array)$options); |
||
1325 | |||
1326 | return $opt[$name] ?? $default; |
||
1327 | } |
||
1328 | |||
1329 | /** |
||
1330 | * Checks if the rectangle passed intersects with the current image |
||
1331 | * |
||
1332 | * @param int $width Width of rectangle |
||
1333 | * @param int $height Height of rectangle |
||
1334 | * @param int $x X-coordinate |
||
1335 | * @param int $y Y-coordinate |
||
1336 | * |
||
1337 | * @return bool|PEAR_Error TRUE if intersects, FALSE if not, |
||
1338 | * and PEAR_Error on error |
||
1339 | * @access public |
||
1340 | */ |
||
1341 | public function intersects($width, $height, $x, $y) |
||
1360 | } |
||
1361 | } |
||
1362 |