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