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) 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 73 $this->args[] = '-resize'; 74 $this->args[] = $size; 75 return $this; 76 } 77 78 /** 79 * @inheritDoc 80 * @throws Exception 81 */ 82 public function crop($width, $height) 83 { 84 if ($width == 0 && $height == 0) { 85 throw new Exception('You can not crop to 0x0'); 86 } 87 88 if ($width == 0) $width = $height; 89 if ($height == 0) $height = $width; 90 91 $size = $width . 'x' . $height; 92 93 $this->args[] = '-resize'; 94 $this->args[] = "$size^"; 95 $this->args[] = '-gravity'; 96 $this->args[] = 'center'; 97 $this->args[] = '-crop'; 98 $this->args[] = "$size+0+0"; 99 $this->args[] = '+repage'; 100 return $this; 101 } 102 103 /** 104 * @inheritDoc 105 * @throws Exception 106 */ 107 public function save($path, $extension = '') 108 { 109 if ($extension === 'jpg') { 110 $extension = 'jpeg'; 111 } 112 113 $this->args[] = '-quality'; 114 $this->args[] = $this->options['quality']; 115 116 if ($extension !== '') $path = $extension . ':' . $path; 117 $this->args[] = $path; 118 119 $args = array_map('escapeshellarg', $this->args); 120 121 $cmd = join(' ', $args); 122 $output = []; 123 $return = 0; 124 exec($cmd, $output, $return); 125 126 if ($return !== 0) { 127 throw new Exception('ImageMagick returned non-zero exit code for ' . $cmd); 128 } 129 } 130} 131