Namespaces

  • Nette
    • Application
    • Caching
    • Collections
    • Config
    • Forms
    • IO
    • Loaders
    • Mail
    • Reflection
    • Security
    • Templates
    • Web
  • None
  • PHP

Classes

  • ArrayTools
  • Callback
  • Component
  • ComponentContainer
  • Configurator
  • DateTime
  • Debug
  • Environment
  • Framework
  • FreezableObject
  • GenericRecursiveIterator
  • Image
  • ImageMagick
  • InstanceFilterIterator
  • Object
  • ObjectMixin
  • Paginator
  • RecursiveComponentIterator
  • ServiceLocator
  • SmartCachingIterator
  • String
  • Tools

Interfaces

  • IComponent
  • IComponentContainer
  • IDebuggable
  • IServiceLocator
  • ITranslator

Exceptions

  • AmbiguousServiceException
  • Overview
  • Namespace
  • Class
  • Tree
  • Other releases
  1: <?php
  2: 
  3: /**
  4:  * This file is part of the Nette Framework (https://nette.org)
  5:  *
  6:  * Copyright (c) 2004 David Grudl (http://davidgrudl.com)
  7:  *
  8:  * For the full copyright and license information, please view
  9:  * the file license.txt that was distributed with this source code.
 10:  */
 11: 
 12: namespace Nette;
 13: 
 14: use Nette;
 15: 
 16: 
 17: 
 18: /**
 19:  * Manipulation with large images using ImageMagick.
 20:  *
 21:  * <code>
 22:  * $image = Image::fromFile('bigphoto.jpg');
 23:  * $image->resize(150, 100);
 24:  * $image->sharpen();
 25:  * $image->send();
 26:  * </code>
 27:  *
 28:  * @author     David Grudl
 29:  */
 30: class ImageMagick extends Image
 31: {
 32:     /** @var string  path to ImageMagick library */
 33:     public static $path = '';
 34: 
 35:     /** @var string */
 36:     public static $tempDir;
 37: 
 38:     /** @var string */
 39:     private $file;
 40: 
 41:     /** @var bool */
 42:     private $isTemporary = FALSE;
 43: 
 44:     /** @var int */
 45:     private $width;
 46: 
 47:     /** @var int */
 48:     private $height;
 49: 
 50: 
 51: 
 52:     /**
 53:      * Wraps image file.
 54:      * @param  string  detected image format
 55:      * @param  string
 56:      */
 57:     public function __construct($file, & $format = NULL)
 58:     {
 59:         if (!is_file($file)) {
 60:             throw new \InvalidArgumentException("File '$file' not found.");
 61:         }
 62:         $format = $this->setFile(realpath($file));
 63:         if ($format === 'JPEG') $format = self::JPEG;
 64:         elseif ($format === 'PNG') $format = self::PNG;
 65:         elseif ($format === 'GIF') $format = self::GIF;
 66:     }
 67: 
 68: 
 69: 
 70:     /**
 71:      * Returns image width.
 72:      * @return int
 73:      */
 74:     public function getWidth()
 75:     {
 76:         return $this->file === NULL ? parent::getWidth() : $this->width;
 77:     }
 78: 
 79: 
 80: 
 81:     /**
 82:      * Returns image height.
 83:      * @return int
 84:      */
 85:     public function getHeight()
 86:     {
 87:         return $this->file === NULL ? parent::getHeight() : $this->height;
 88:     }
 89: 
 90: 
 91: 
 92:     /**
 93:      * Returns image GD resource.
 94:      * @return resource
 95:      */
 96:     public function getImageResource()
 97:     {
 98:         if ($this->file !== NULL) {
 99:             if (!$this->isTemporary) {
100:                 $this->execute("convert -strip %input %output", self::PNG);
101:             }
102:             $this->setImageResource(imagecreatefrompng($this->file));
103:             if ($this->isTemporary) {
104:                 unlink($this->file);
105:             }
106:             $this->file = NULL;
107:         }
108: 
109:         return parent::getImageResource();
110:     }
111: 
112: 
113: 
114:     /**
115:      * Resizes image.
116:      * @param  mixed  width in pixels or percent
117:      * @param  mixed  height in pixels or percent
118:      * @param  int    flags
119:      * @return ImageMagick  provides a fluent interface
120:      */
121:     public function resize($width, $height, $flags = self::FIT)
122:     {
123:         if ($this->file === NULL) {
124:             return parent::resize($width, $height, $flags);
125:         }
126: 
127:         $mirror = '';
128:         if ($width < 0) $mirror .= ' -flop';
129:         if ($height < 0) $mirror .= ' -flip';
130:         list($newWidth, $newHeight) = self::calculateSize($this->getWidth(), $this->getHeight(), $width, $height, $flags);
131:         $this->execute("convert -resize {$newWidth}x{$newHeight}! {$mirror} -strip %input %output", self::PNG);
132:         return $this;
133:     }
134: 
135: 
136: 
137:     /**
138:      * Crops image.
139:      * @param  mixed  x-offset in pixels or percent
140:      * @param  mixed  y-offset in pixels or percent
141:      * @param  mixed  width in pixels or percent
142:      * @param  mixed  height in pixels or percent
143:      * @return ImageMagick  provides a fluent interface
144:      */
145:     public function crop($left, $top, $width, $height)
146:     {
147:         if ($this->file === NULL) {
148:             return parent::crop($left, $top, $width, $height);
149:         }
150: 
151:         list($left, $top, $width, $height) = self::calculateCutout($this->getWidth(), $this->getHeight(), $left, $top, $width, $height);
152:         $this->execute("convert -crop {$width}x{$height}+{$left}+{$top} -strip %input %output", self::PNG);
153:         return $this;
154:     }
155: 
156: 
157: 
158:     /**
159:      * Saves image to the file.
160:      * @param  string  filename
161:      * @param  int  quality 0..100 (for JPEG and PNG)
162:      * @param  int  optional image type
163:      * @return bool TRUE on success or FALSE on failure.
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:      * Change and identify image file.
186:      * @param  string  filename
187:      * @return string  detected image format
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:      * Executes command.
204:      * @param  string  command
205:      * @param  string|bool  process output?
206:      * @return string
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); // $status: 0 - ok, 1 - error, 127 - command not found?
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:      * Delete temporary files.
239:      * @return void
240:      */
241:     public function __destruct()
242:     {
243:         if ($this->file !== NULL && $this->isTemporary) {
244:             unlink($this->file);
245:         }
246:     }
247: 
248: }
249: 
Nette Framework 0.9.7 API documentation generated by ApiGen 2.3.0