192a8473aSAndreas Gohr<?php 292a8473aSAndreas Gohr 392a8473aSAndreas Gohr 492a8473aSAndreas Gohrnamespace splitbrain\slika; 592a8473aSAndreas Gohr 6*5c25a071SAndreas Gohr/** 7*5c25a071SAndreas Gohr * Image Processing Adapter for ImageMagick's command line utility `convert` 8*5c25a071SAndreas Gohr */ 992a8473aSAndreas Gohrclass ImageMagickAdapter extends Adapter 1092a8473aSAndreas Gohr{ 1192a8473aSAndreas Gohr /** @var array the CLI arguments to run imagemagick */ 1292a8473aSAndreas Gohr protected $args = []; 1392a8473aSAndreas Gohr 1492a8473aSAndreas Gohr /** @inheritDoc */ 1592a8473aSAndreas Gohr public function __construct($imagepath, $options = []) 1692a8473aSAndreas Gohr { 1792a8473aSAndreas Gohr parent::__construct($imagepath, $options); 1892a8473aSAndreas Gohr 1992a8473aSAndreas Gohr if (!is_executable($this->options['imconvert'])) { 2092a8473aSAndreas Gohr throw new Exception('Can not find or run ' . $this->options['imconvert']); 2192a8473aSAndreas Gohr } 2292a8473aSAndreas Gohr 2392a8473aSAndreas Gohr $this->args[] = $this->options['imconvert']; 2492a8473aSAndreas Gohr $this->args[] = $imagepath; 2592a8473aSAndreas Gohr } 2692a8473aSAndreas Gohr 2792a8473aSAndreas Gohr /** @inheritDoc */ 2892a8473aSAndreas Gohr public function autorotate() 2992a8473aSAndreas Gohr { 3092a8473aSAndreas Gohr $this->args[] = '-auto-orient'; 3192a8473aSAndreas Gohr return $this; 3292a8473aSAndreas Gohr } 3392a8473aSAndreas Gohr 3492a8473aSAndreas Gohr /** @inheritDoc */ 3592a8473aSAndreas Gohr public function rotate($orientation) 3692a8473aSAndreas Gohr { 3792a8473aSAndreas Gohr $orientation = (int)$orientation; 3892a8473aSAndreas Gohr if ($orientation < 0 || $orientation > 8) { 3992a8473aSAndreas Gohr throw new Exception('Unknown rotation given'); 4092a8473aSAndreas Gohr } 4192a8473aSAndreas Gohr 4292a8473aSAndreas Gohr // rotate 4392a8473aSAndreas Gohr $this->args[] = '-rotate'; 4492a8473aSAndreas Gohr if (in_array($orientation, [3, 4])) { 4592a8473aSAndreas Gohr $this->args[] = '180'; 4692a8473aSAndreas Gohr } elseif (in_array($orientation, [5, 6])) { 4792a8473aSAndreas Gohr $this->args[] = '90'; 4892a8473aSAndreas Gohr } elseif (in_array($orientation, [7, 8])) { 4992a8473aSAndreas Gohr $this->args[] = '270'; 5092a8473aSAndreas Gohr } 5192a8473aSAndreas Gohr 5292a8473aSAndreas Gohr // additionally flip 5392a8473aSAndreas Gohr if (in_array($orientation, [2, 5, 7, 4])) { 5492a8473aSAndreas Gohr $this->args[] = '-flop'; 5592a8473aSAndreas Gohr } 5692a8473aSAndreas Gohr return $this; 5792a8473aSAndreas Gohr } 5892a8473aSAndreas Gohr 5992a8473aSAndreas Gohr /** 6092a8473aSAndreas Gohr * @inheritDoc 6192a8473aSAndreas Gohr * @throws Exception 6292a8473aSAndreas Gohr */ 6392a8473aSAndreas Gohr public function resize($width, $height) 6492a8473aSAndreas Gohr { 6592a8473aSAndreas Gohr if ($width == 0 && $height == 0) { 6692a8473aSAndreas Gohr throw new Exception('You can not resize to 0x0'); 6792a8473aSAndreas Gohr } 6892a8473aSAndreas Gohr if ($width == 0) $width = ''; 6992a8473aSAndreas Gohr if ($height == 0) $height = ''; 7092a8473aSAndreas Gohr 7192a8473aSAndreas Gohr $size = $width . 'x' . $height; 7292a8473aSAndreas Gohr 7392a8473aSAndreas Gohr $this->args[] = '-resize'; 7492a8473aSAndreas Gohr $this->args[] = $size; 7592a8473aSAndreas Gohr return $this; 7692a8473aSAndreas Gohr } 7792a8473aSAndreas Gohr 7892a8473aSAndreas Gohr /** 7992a8473aSAndreas Gohr * @inheritDoc 8092a8473aSAndreas Gohr * @throws Exception 8192a8473aSAndreas Gohr */ 8292a8473aSAndreas Gohr public function crop($width, $height) 8392a8473aSAndreas Gohr { 8492a8473aSAndreas Gohr if ($width == 0 && $height == 0) { 8592a8473aSAndreas Gohr throw new Exception('You can not crop to 0x0'); 8692a8473aSAndreas Gohr } 8792a8473aSAndreas Gohr 8892a8473aSAndreas Gohr if ($width == 0) $width = $height; 8992a8473aSAndreas Gohr if ($height == 0) $height = $width; 9092a8473aSAndreas Gohr 91*5c25a071SAndreas Gohr $size = $width . 'x' . $height; 92*5c25a071SAndreas Gohr 93*5c25a071SAndreas Gohr $this->args[] = '-resize'; 94*5c25a071SAndreas Gohr $this->args[] = "$size^"; 9592a8473aSAndreas Gohr $this->args[] = '-gravity'; 9692a8473aSAndreas Gohr $this->args[] = 'center'; 9792a8473aSAndreas Gohr $this->args[] = '-crop'; 98*5c25a071SAndreas Gohr $this->args[] = "$size+0+0"; 9992a8473aSAndreas Gohr $this->args[] = '+repage'; 10092a8473aSAndreas Gohr return $this; 10192a8473aSAndreas Gohr } 10292a8473aSAndreas Gohr 10392a8473aSAndreas Gohr /** 10492a8473aSAndreas Gohr * @inheritDoc 10592a8473aSAndreas Gohr * @throws Exception 10692a8473aSAndreas Gohr */ 10792a8473aSAndreas Gohr public function save($path, $extension = '') 10892a8473aSAndreas Gohr { 10992a8473aSAndreas Gohr if ($extension === 'jpg') { 11092a8473aSAndreas Gohr $extension = 'jpeg'; 11192a8473aSAndreas Gohr } 11292a8473aSAndreas Gohr 11392a8473aSAndreas Gohr $this->args[] = '-quality'; 11492a8473aSAndreas Gohr $this->args[] = $this->options['quality']; 11592a8473aSAndreas Gohr 11692a8473aSAndreas Gohr if ($extension !== '') $path = $extension . ':' . $path; 11792a8473aSAndreas Gohr $this->args[] = $path; 11892a8473aSAndreas Gohr 11992a8473aSAndreas Gohr $args = array_map('escapeshellarg', $this->args); 12092a8473aSAndreas Gohr 12192a8473aSAndreas Gohr $cmd = join(' ', $args); 12292a8473aSAndreas Gohr $output = []; 12392a8473aSAndreas Gohr $return = 0; 12492a8473aSAndreas Gohr exec($cmd, $output, $return); 12592a8473aSAndreas Gohr 12692a8473aSAndreas Gohr if ($return !== 0) { 12792a8473aSAndreas Gohr throw new Exception('ImageMagick returned non-zero exit code for ' . $cmd); 12892a8473aSAndreas Gohr } 12992a8473aSAndreas Gohr } 13092a8473aSAndreas Gohr} 131