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