1: <?php
2:
3: 4: 5: 6: 7: 8: 9: 10: 11:
12:
13:
14:
15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26:
27: class ImageMagick extends Image
28: {
29:
30: public static $path = '';
31:
32:
33: public static $tempDir;
34:
35:
36: private $file;
37:
38:
39: private $isTemporary = FALSE;
40:
41:
42: private $width;
43:
44:
45: private $height;
46:
47:
48:
49: 50: 51: 52: 53:
54: public function __construct($file, & $format = NULL)
55: {
56: if (!is_file($file)) {
57: throw new InvalidArgumentException("File '$file' not found.");
58: }
59: $format = $this->setFile(realpath($file));
60: if ($format === 'JPEG') $format = self::JPEG;
61: elseif ($format === 'PNG') $format = self::PNG;
62: elseif ($format === 'GIF') $format = self::GIF;
63: }
64:
65:
66:
67: 68: 69: 70:
71: public function getWidth()
72: {
73: return $this->file === NULL ? parent::getWidth() : $this->width;
74: }
75:
76:
77:
78: 79: 80: 81:
82: public function getHeight()
83: {
84: return $this->file === NULL ? parent::getHeight() : $this->height;
85: }
86:
87:
88:
89: 90: 91: 92:
93: public function getImageResource()
94: {
95: if ($this->file !== NULL) {
96: if (!$this->isTemporary) {
97: $this->execute("convert -strip %input %output", self::PNG);
98: }
99: $this->setImageResource(imagecreatefrompng($this->file));
100: if ($this->isTemporary) {
101: unlink($this->file);
102: }
103: $this->file = NULL;
104: }
105:
106: return parent::getImageResource();
107: }
108:
109:
110:
111: 112: 113: 114: 115: 116: 117:
118: public function resize($width, $height, $flags = self::FIT)
119: {
120: if ($this->file === NULL) {
121: return parent::resize($width, $height, $flags);
122: }
123:
124: $mirror = '';
125: if ($width < 0) $mirror .= ' -flop';
126: if ($height < 0) $mirror .= ' -flip';
127: list($newWidth, $newHeight) = self::calculateSize($this->getWidth(), $this->getHeight(), $width, $height, $flags);
128: $this->execute("convert -resize {$newWidth}x{$newHeight}! {$mirror} -strip %input %output", self::PNG);
129: return $this;
130: }
131:
132:
133:
134: 135: 136: 137: 138: 139: 140: 141:
142: public function crop($left, $top, $width, $height)
143: {
144: if ($this->file === NULL) {
145: return parent::crop($left, $top, $width, $height);
146: }
147:
148: $left = max(0, (int) $left);
149: $top = max(0, (int) $top);
150: $width = min((int) $width, $this->getWidth() - $left);
151: $height = min((int) $height, $this->getHeight() - $top);
152: $this->execute("convert -crop {$width}x{$height}+{$left}+{$top} -strip %input %output", self::PNG);
153: return $this;
154: }
155:
156:
157:
158: 159: 160: 161: 162: 163: 164:
165: public function save($file = NULL, $quality = NULL, $type = NULL)
166: {
167: if ($this->file === NULL) {
168: return parent::save($file, $quality, $type);
169: }
170:
171: $quality = $quality === NULL ? '' : '-quality ' . max(0, min(100, (int) $quality));
172: if ($file === NULL) {
173: $this->execute("convert $quality -strip %input %output", $type === NULL ? self::PNG : $type);
174: readfile($this->file);
175:
176: } else {
177: $this->execute("convert $quality -strip %input %output", (string) $file);
178: }
179: return TRUE;
180: }
181:
182:
183:
184: 185: 186: 187: 188:
189: private function setFile($file)
190: {
191: $this->file = $file;
192: $res = $this->execute('identify -format "%w,%h,%m" ' . escapeshellarg($this->file));
193: if (!$res) {
194: throw new Exception("Unknown image type in file '$file' or ImageMagick not available.");
195: }
196: list($this->width, $this->height, $format) = explode(',', $res, 3);
197: return $format;
198: }
199:
200:
201:
202: 203: 204: 205: 206: 207:
208: private function execute($command, $output = NULL)
209: {
210: $command = str_replace('%input', escapeshellarg($this->file), $command);
211: if ($output) {
212: $newFile = is_string($output)
213: ? $output
214: : (self::$tempDir ? self::$tempDir : dirname($this->file)) . '/' . uniqid('_tempimage', TRUE) . image_type_to_extension($output);
215: $command = str_replace('%output', escapeshellarg($newFile), $command);
216: }
217:
218: $lines = array();
219: exec(self::$path . $command, $lines, $status); 220:
221: if ($output) {
222: if ($status != 0) {
223: throw new Exception("Unknown error while calling ImageMagick.");
224: }
225: if ($this->isTemporary) {
226: unlink($this->file);
227: }
228: $this->setFile($newFile);
229: $this->isTemporary = !is_string($output);
230: }
231:
232: return $lines ? $lines[0] : FALSE;
233: }
234:
235:
236:
237: 238: 239: 240:
241: public function __destruct()
242: {
243: if ($this->file !== NULL && $this->isTemporary) {
244: unlink($this->file);
245: }
246: }
247:
248: }