File indexing completed on 2025-03-02 05:33:39

0001 <?php
0002 
0003 namespace Intervention\Image;
0004 
0005 use Psr\Http\Message\ResponseInterface;
0006 use Psr\Http\Message\StreamInterface;
0007 
0008 /**
0009  * @method \Intervention\Image\Image backup(string $name = 'default')                                                                                                     Backups current image state as fallback for reset method under an optional name. Overwrites older state on every call, unless a different name is passed.
0010  * @method \Intervention\Image\Image blur(int $amount = 1)                                                                                                            Apply a gaussian blur filter with a optional amount on the current image. Use values between 0 and 100.
0011  * @method \Intervention\Image\Image brightness(int $level)                                                                                                           Changes the brightness of the current image by the given level. Use values between -100 for min. brightness. 0 for no change and +100 for max. brightness.
0012  * @method \Intervention\Image\Image cache(\Closure $callback, int $lifetime = null, boolean $returnObj = false)                                                      Method to create a new cached image instance from a Closure callback. Pass a lifetime in minutes for the callback and decide whether you want to get an Intervention Image instance as return value or just receive the image stream.
0013  * @method \Intervention\Image\Image canvas(int $width, int $height, mixed $bgcolor = null)                                                                       Factory method to create a new empty image instance with given width and height. You can define a background-color optionally. By default the canvas background is transparent.
0014  * @method \Intervention\Image\Image circle(int $radius, int $x, int $y, \Closure $callback = null)                                                           Draw a circle at given x, y, coordinates with given radius. You can define the appearance of the circle by an optional closure callback.
0015  * @method \Intervention\Image\Image colorize(int $red, int $green, int $blue)                                                                                Change the RGB color values of the current image on the given channels red, green and blue. The input values are normalized so you have to include parameters from 100 for maximum color value. 0 for no change and -100 to take out all the certain color on the image.
0016  * @method \Intervention\Image\Image contrast(int $level)                                                                                                             Changes the contrast of the current image by the given level. Use values between -100 for min. contrast 0 for no change and +100 for max. contrast.
0017  * @method \Intervention\Image\Image crop(int $width, int $height, int $x = null, int $y = null)                                                          Cut out a rectangular part of the current image with given width and height. Define optional x,y coordinates to move the top-left corner of the cutout to a certain position.
0018  * @method void                      destroy()                                                                                                                            Frees memory associated with the current image instance before the PHP script ends. Normally resources are destroyed automatically after the script is finished.
0019  * @method \Intervention\Image\Image ellipse(int $width, int $height, int $x, int $y, \Closure $callback = null)                                          Draw a colored ellipse at given x, y, coordinates. You can define width and height and set the appearance of the circle by an optional closure callback.
0020  * @method mixed                     exif(string $key = null)                                                                                                             Read Exif meta data from current image.
0021  * @method mixed                     iptc(string $key = null)                                                                                                             Read Iptc meta data from current image.
0022  * @method \Intervention\Image\Image fill(mixed $filling, int $x = null, int $y = null)                                                                           Fill current image with given color or another image used as tile for filling. Pass optional x, y coordinates to start at a certain point.
0023  * @method \Intervention\Image\Image flip(string $mode = 'h')                                                                                                             Mirror the current image horizontally or vertically by specifying the mode.
0024  * @method \Intervention\Image\Image fit(int $width, int $height = null, \Closure $callback = null, string $position = 'center')                                  Combine cropping and resizing to format image in a smart way. The method will find the best fitting aspect ratio of your given width and height on the current image automatically, cut it out and resize it to the given dimension. You may pass an optional Closure callback as third parameter, to prevent possible upsizing and a custom position of the cutout as fourth parameter.
0025  * @method \Intervention\Image\Image gamma(float $correction)                                                                                                             Performs a gamma correction operation on the current image.
0026  * @method \Intervention\Image\Image greyscale()                                                                                                                          Turns image into a greyscale version.
0027  * @method \Intervention\Image\Image heighten(int $height, \Closure $callback = null)                                                                                 Resizes the current image to new height, constraining aspect ratio. Pass an optional Closure callback as third parameter, to apply additional constraints like preventing possible upsizing.
0028  * @method \Intervention\Image\Image insert(mixed $source, string $position = 'top-left', int $x = 0, int $y = 0)                                                 Paste a given image source over the current image with an optional position and a offset coordinate. This method can be used to apply another image as watermark because the transparency values are maintained.
0029  * @method \Intervention\Image\Image interlace(boolean $interlace = true)                                                                                                 Determine whether an image should be encoded in interlaced or standard mode by toggling interlace mode with a boolean parameter. If an JPEG image is set interlaced the image will be processed as a progressive JPEG.
0030  * @method \Intervention\Image\Image invert()                                                                                                                             Reverses all colors of the current image.
0031  * @method \Intervention\Image\Image limitColors(int $count, mixed $matte = null)                                                                                     Method converts the existing colors of the current image into a color table with a given maximum count of colors. The function preserves as much alpha channel information as possible and blends transarent pixels against a optional matte color.
0032  * @method \Intervention\Image\Image line(int $x1, int $y1, int $x2, int $y2, \Closure $callback = null)                                                  Draw a line from x,y point 1 to x,y point 2 on current image. Define color and/or width of line in an optional Closure callback.
0033  * @method \Intervention\Image\Image make(mixed $source)                                                                                                                  Universal factory method to create a new image instance from source, which can be a filepath, a GD image resource, an Imagick object or a binary image data.
0034  * @method \Intervention\Image\Image mask(mixed $source, boolean $mask_with_alpha)                                                                                        Apply a given image source as alpha mask to the current image to change current opacity. Mask will be resized to the current image size. By default a greyscale version of the mask is converted to alpha values, but you can set mask_with_alpha to apply the actual alpha channel. Any transparency values of the current image will be maintained.
0035  * @method \Intervention\Image\Image opacity(int $transparency)                                                                                                       Set the opacity in percent of the current image ranging from 100% for opaque and 0% for full transparency.
0036  * @method \Intervention\Image\Image orientate()                                                                                                                          This method reads the EXIF image profile setting 'Orientation' and performs a rotation on the image to display the image correctly.
0037  * @method mixed                     pickColor(int $x, int $y, string $format = 'array')                                                                          Pick a color at point x, y out of current image and return in optional given format.
0038  * @method \Intervention\Image\Image pixel(mixed $color, int $x, int $y)                                                                                          Draw a single pixel in given color on x, y position.
0039  * @method \Intervention\Image\Image pixelate(int $size)                                                                                                              Applies a pixelation effect to the current image with a given size of pixels.
0040  * @method \Intervention\Image\Image polygon(array $points, \Closure $callback = null)                                                                                    Draw a colored polygon with given points. You can define the appearance of the polygon by an optional closure callback.
0041  * @method \Intervention\Image\Image rectangle(int $x1, int $y1, int $x2, int $y2, \Closure $callback = null)                                             Draw a colored rectangle on current image with top-left corner on x,y point 1 and bottom-right corner at x,y point 2. Define the overall appearance of the shape by passing a Closure callback as an optional parameter.
0042  * @method \Intervention\Image\Image reset(string $name = 'default')                                                                                                      Resets all of the modifications to a state saved previously by backup under an optional name.
0043  * @method \Intervention\Image\Image resize(int $width, int $height = null, \Closure $callback = null)                                                                   Resizes current image based on given width and/or height. To contraint the resize command, pass an optional Closure callback as third parameter.
0044  * @method \Intervention\Image\Image resizeCanvas(int $width, int $height, string $anchor = 'center', boolean $relative = false, mixed $bgcolor = null)           Resize the boundaries of the current image to given width and height. An anchor can be defined to determine from what point of the image the resizing is going to happen. Set the mode to relative to add or subtract the given width or height to the actual image dimensions. You can also pass a background color for the emerging area of the image.
0045  * @method mixed                     response(string $format = null, int $quality = 90)                                                                               Sends HTTP response with current image in given format and quality.
0046  * @method \Intervention\Image\Image rotate(float $angle, mixed $bgcolor = null)                                                                                          Rotate the current image counter-clockwise by a given angle. Optionally define a background color for the uncovered zone after the rotation.
0047  * @method \Intervention\Image\Image sharpen(int $amount = 10)                                                                                                        Sharpen current image with an optional amount. Use values between 0 and 100.
0048  * @method \Intervention\Image\Image text(string $text, int $x = 0, int $y = 0, \Closure $callback = null)                                                        Write a text string to the current image at an optional x,y basepoint position. You can define more details like font-size, font-file and alignment via a callback as the fourth parameter.
0049  * @method \Intervention\Image\Image trim(string $base = 'top-left', array $away = array('top', 'bottom', 'left', 'right'), int $tolerance = 0, int $feather = 0) Trim away image space in given color. Define an optional base to pick a color at a certain position and borders that should be trimmed away. You can also set an optional tolerance level, to trim similar colors and add a feathering border around the trimed image.
0050  * @method \Intervention\Image\Image widen(int $width, \Closure $callback = null)                                                                                     Resizes the current image to new width, constraining aspect ratio. Pass an optional Closure callback as third parameter, to apply additional constraints like preventing possible upsizing.
0051  * @method StreamInterface           stream(string $format = null, int $quality = 90)                                                                                 Build PSR-7 compatible StreamInterface with current image in given format and quality.
0052  * @method ResponseInterface         psrResponse(string $format = null, int $quality = 90)                                                                            Build PSR-7 compatible ResponseInterface with current image in given format and quality.
0053  */
0054 class Image extends File
0055 {
0056     /**
0057      * Instance of current image driver
0058      *
0059      * @var AbstractDriver
0060      */
0061     protected $driver;
0062 
0063     /**
0064      * Image resource/object of current image processor
0065      *
0066      * @var mixed
0067      */
0068     protected $core;
0069 
0070     /**
0071      * Array of Image resource backups of current image processor
0072      *
0073      * @var array
0074      */
0075     protected $backups = [];
0076 
0077     /**
0078      * Last image encoding result
0079      *
0080      * @var string
0081      */
0082     public $encoded = '';
0083 
0084     /**
0085      * Creates a new Image instance
0086      *
0087      * @param AbstractDriver $driver
0088      * @param mixed  $core
0089      */
0090     public function __construct(AbstractDriver $driver = null, $core = null)
0091     {
0092         $this->driver = $driver;
0093         $this->core = $core;
0094     }
0095 
0096     /**
0097      * Magic method to catch all image calls
0098      * usually any AbstractCommand
0099      *
0100      * @param  string $name
0101      * @param  Array  $arguments
0102      * @return mixed
0103      */
0104     public function __call($name, $arguments)
0105     {
0106         $command = $this->driver->executeCommand($this, $name, $arguments);
0107         return $command->hasOutput() ? $command->getOutput() : $this;
0108     }
0109 
0110     /**
0111      * Starts encoding of current image
0112      *
0113      * @param  string  $format
0114      * @param  int     $quality
0115      * @return \Intervention\Image\Image
0116      */
0117     public function encode($format = null, $quality = 90)
0118     {
0119         return $this->driver->encode($this, $format, $quality);
0120     }
0121 
0122     /**
0123      * Saves encoded image in filesystem
0124      *
0125      * @param  string  $path
0126      * @param  int     $quality
0127      * @return \Intervention\Image\Image
0128      */
0129     public function save($path = null, $quality = null)
0130     {
0131         $path = is_null($path) ? $this->basePath() : $path;
0132 
0133         if (is_null($path)) {
0134             throw new Exception\NotWritableException(
0135                 "Can't write to undefined path."
0136             );
0137         }
0138 
0139         $data = $this->encode(pathinfo($path, PATHINFO_EXTENSION), $quality);
0140         $saved = @file_put_contents($path, $data);
0141 
0142         if ($saved === false) {
0143             throw new Exception\NotWritableException(
0144                 "Can't write image data to path ({$path})"
0145             );
0146         }
0147 
0148         // set new file info
0149         $this->setFileInfoFromPath($path);
0150 
0151         return $this;
0152     }
0153 
0154     /**
0155      * Runs a given filter on current image
0156      *
0157      * @param  FiltersFilterInterface $filter
0158      * @return \Intervention\Image\Image
0159      */
0160     public function filter(Filters\FilterInterface $filter)
0161     {
0162         return $filter->applyFilter($this);
0163     }
0164 
0165     /**
0166      * Returns current image driver
0167      *
0168      * @return \Intervention\Image\AbstractDriver
0169      */
0170     public function getDriver()
0171     {
0172         return $this->driver;
0173     }
0174 
0175     /**
0176      * Sets current image driver
0177      * @param AbstractDriver $driver
0178      */
0179     public function setDriver(AbstractDriver $driver)
0180     {
0181         $this->driver = $driver;
0182 
0183         return $this;
0184     }
0185 
0186     /**
0187      * Returns current image resource/obj
0188      *
0189      * @return mixed
0190      */
0191     public function getCore()
0192     {
0193         return $this->core;
0194     }
0195 
0196     /**
0197      * Sets current image resource
0198      *
0199      * @param mixed $core
0200      */
0201     public function setCore($core)
0202     {
0203         $this->core = $core;
0204 
0205         return $this;
0206     }
0207 
0208     /**
0209      * Returns current image backup
0210      *
0211      * @param string $name
0212      * @return mixed
0213      */
0214     public function getBackup($name = null)
0215     {
0216         $name = is_null($name) ? 'default' : $name;
0217 
0218         if ( ! $this->backupExists($name)) {
0219             throw new \Intervention\Image\Exception\RuntimeException(
0220                 "Backup with name ({$name}) not available. Call backup() before reset()."
0221             );
0222         }
0223 
0224         return $this->backups[$name];
0225     }
0226 
0227     /**
0228      * Returns all backups attached to image
0229      *
0230      * @return array
0231      */
0232     public function getBackups()
0233     {
0234         return $this->backups;
0235     }
0236 
0237     /**
0238      * Sets current image backup
0239      *
0240      * @param mixed  $resource
0241      * @param string $name
0242      * @return self
0243      */
0244     public function setBackup($resource, $name = null)
0245     {
0246         $name = is_null($name) ? 'default' : $name;
0247 
0248         $this->backups[$name] = $resource;
0249 
0250         return $this;
0251     }
0252 
0253     /**
0254      * Checks if named backup exists
0255      *
0256      * @param  string $name
0257      * @return bool
0258      */
0259     private function backupExists($name)
0260     {
0261         return array_key_exists($name, $this->backups);
0262     }
0263 
0264     /**
0265      * Checks if current image is already encoded
0266      *
0267      * @return boolean
0268      */
0269     public function isEncoded()
0270     {
0271         return ! empty($this->encoded);
0272     }
0273 
0274     /**
0275      * Returns encoded image data of current image
0276      *
0277      * @return string
0278      */
0279     public function getEncoded()
0280     {
0281         return $this->encoded;
0282     }
0283 
0284     /**
0285      * Sets encoded image buffer
0286      *
0287      * @param string $value
0288      */
0289     public function setEncoded($value)
0290     {
0291         $this->encoded = $value;
0292 
0293         return $this;
0294     }
0295 
0296     /**
0297      * Calculates current image width
0298      *
0299      * @return int
0300      */
0301     public function getWidth()
0302     {
0303         return $this->getSize()->width;
0304     }
0305 
0306     /**
0307      * Alias of getWidth()
0308      *
0309      * @return int
0310      */
0311     public function width()
0312     {
0313         return $this->getWidth();
0314     }
0315 
0316     /**
0317      * Calculates current image height
0318      *
0319      * @return int
0320      */
0321     public function getHeight()
0322     {
0323         return $this->getSize()->height;
0324     }
0325 
0326     /**
0327      * Alias of getHeight
0328      *
0329      * @return int
0330      */
0331     public function height()
0332     {
0333         return $this->getHeight();
0334     }
0335 
0336     /**
0337      * Reads mime type
0338      *
0339      * @return string
0340      */
0341     public function mime()
0342     {
0343         return $this->mime;
0344     }
0345 
0346     /**
0347      * Returns encoded image data in string conversion
0348      *
0349      * @return string
0350      */
0351     public function __toString()
0352     {
0353         return $this->encoded;
0354     }
0355 
0356     /**
0357      * Cloning an image
0358      */
0359     public function __clone()
0360     {
0361         $this->core = $this->driver->cloneCore($this->core);
0362     }
0363 }