1<?php 2 3 4namespace splitbrain\slika; 5 6/** 7 * Image Processing Adapter for ImageMagick's command line utility `convert` 8 */ 9class ImageMagickAdapter extends Adapter 10{ 11 /** @var array the CLI arguments to run imagemagick */ 12 protected $args = []; 13 14 /** @inheritDoc */ 15 public function __construct($imagepath, $options = []) 16 { 17 parent::__construct($imagepath, $options); 18 19 if (!is_executable($this->options['imconvert'])) { 20 throw new Exception('Can not find or run ' . $this->options['imconvert']); 21 } 22 23 $this->args[] = $this->options['imconvert']; 24 $this->args[] = $imagepath; 25 } 26 27 /** @inheritDoc */ 28 public function autorotate() 29 { 30 $this->args[] = '-auto-orient'; 31 return $this; 32 } 33 34 /** @inheritDoc */ 35 public function rotate($orientation) 36 { 37 $orientation = (int)$orientation; 38 if ($orientation < 0 || $orientation > 8) { 39 throw new Exception('Unknown rotation given'); 40 } 41 42 // rotate 43 $this->args[] = '-rotate'; 44 if (in_array($orientation, [3, 4])) { 45 $this->args[] = '180'; 46 } elseif (in_array($orientation, [5, 6])) { 47 $this->args[] = '90'; 48 } elseif (in_array($orientation, [7, 8])) { 49 $this->args[] = '270'; 50 } 51 52 // additionally flip 53 if (in_array($orientation, [2, 5, 7, 4])) { 54 $this->args[] = '-flop'; 55 } 56 return $this; 57 } 58 59 /** 60 * @inheritDoc 61 * @throws Exception 62 */ 63 public function resize($width, $height, $upscale = true) 64 { 65 if ($width == 0 && $height == 0) { 66 throw new Exception('You can not resize to 0x0'); 67 } 68 if ($width == 0) $width = ''; 69 if ($height == 0) $height = ''; 70 71 $size = $width . 'x' . $height; 72 if (!$upscale) $size .= '>'; 73 74 $this->args[] = '-resize'; 75 $this->args[] = $size; 76 return $this; 77 } 78 79 /** 80 * @inheritDoc 81 * @throws Exception 82 */ 83 public function crop($width, $height, $upscale = true) 84 { 85 $width = (int)$width; 86 $height = (int)$height; 87 if ($width == 0 && $height == 0) { 88 throw new Exception('You can not crop to 0x0'); 89 } 90 91 if ($width == 0) $width = $height; 92 if ($height == 0) $height = $width; 93 94 $size = $width . 'x' . $height; 95 96 $this->args[] = '-resize'; 97 $this->args[] = $upscale ? "$size^" : "$size^>"; 98 $this->args[] = '-gravity'; 99 $this->args[] = 'center'; 100 $this->args[] = '-crop'; 101 $this->args[] = "$size+0+0"; 102 $this->args[] = '+repage'; 103 return $this; 104 } 105 106 /** 107 * @inheritDoc 108 * @throws Exception 109 */ 110 public function save($path, $extension = '') 111 { 112 if ($extension === 'jpg') { 113 $extension = 'jpeg'; 114 } 115 116 $this->args[] = '-quality'; 117 $this->args[] = $this->options['quality']; 118 119 if ($extension !== '') $path = $extension . ':' . $path; 120 $this->args[] = $path; 121 122 $args = array_map('escapeshellarg', $this->args); 123 124 $cmd = join(' ', $args); 125 $output = []; 126 $return = 0; 127 exec($cmd, $output, $return); 128 129 if ($return !== 0) { 130 throw new Exception('ImageMagick returned non-zero exit code for ' . $cmd); 131 } 132 } 133} 134