code:
<?php

namespace Intervention\Image\Gd;

use Intervention\Image\Exception\NotReadableException;
use Intervention\Image\Exception\NotSupportedException;
use Intervention\Image\Image;

class Decoder extends \Intervention\Image\AbstractDecoder
{
    /**
     * Initiates new image from path in filesystem
     *
     * @param  string $path
     * @return \Intervention\Image\Image
     */
    public function initFromPath($path)
    {
        if ( ! file_exists($path)) {
            throw new NotReadableException(
                "Unable to find file ({$path})."
            );
        }

        // get mime type of file
        $mime = finfo_file(finfo_open(FILEINFO_MIME_TYPE), $path);

        // define core
        switch (strtolower($mime)) {
            case 'image/png':
            case 'image/x-png':
                $core = @imagecreatefrompng($path);
                break;

            case 'image/jpg':
            case 'image/jpeg':
            case 'image/pjpeg':
                $core = @imagecreatefromjpeg($path);
                if (!$core) {
                    $core= @imagecreatefromstring(file_get_contents($path));
                }
                break;

            case 'image/gif':
                $core = @imagecreatefromgif($path);
                break;

            case 'image/webp':
            case 'image/x-webp':
                if ( ! function_exists('imagecreatefromwebp')) {
                    throw new NotReadableException(
                        "Unsupported image type. GD/PHP installation does not support WebP format."
                    );
                }
                $core = @imagecreatefromwebp($path);
                break;

            default:
                throw new NotReadableException(
                    "Unsupported image type. GD driver is only able to decode JPG, PNG, GIF or WebP files."
                );
        }

        if (empty($core)) {
            throw new NotReadableException(
                "Unable to decode image from file ({$path})."
            );
        }

        $this->gdResourceToTruecolor($core);

        // build image
        $image = $this->initFromGdResource($core);
        $image->mime = $mime;
        $image->setFileInfoFromPath($path);

        return $image;
    }

    /**
     * Initiates new image from GD resource
     *
     * @param  Resource $resource
     * @return \Intervention\Image\Image
     */
    public function initFromGdResource($resource)
    {
        return new Image(new Driver, $resource);
    }

    /**
     * Initiates new image from Imagick object
     *
     * @param  Imagick $object
     * @return \Intervention\Image\Image
     */
    public function initFromImagick(\Imagick $object)
    {
        throw new NotSupportedException(
            "Gd driver is unable to init from Imagick object."
        );
    }

    /**
     * Initiates new image from binary data
     *
     * @param  string $data
     * @return \Intervention\Image\Image
     */
    public function initFromBinary($binary)
    {
        $resource = @imagecreatefromstring($binary);

        if ($resource === false) {
             throw new NotReadableException(
                "Unable to init from given binary data."
            );
        }

        $image = $this->initFromGdResource($resource);
        $image->mime = finfo_buffer(finfo_open(FILEINFO_MIME_TYPE), $binary);

        return $image;
    }

    /**
     * Transform GD resource into Truecolor version
     *
     * @param  resource $resource
     * @return bool
     */
    public function gdResourceToTruecolor(&$resource)
    {
        $width = imagesx($resource);
        $height = imagesy($resource);

        // new canvas
        $canvas = imagecreatetruecolor($width, $height);

        // fill with transparent color
        imagealphablending($canvas, false);
        $transparent = imagecolorallocatealpha($canvas, 255, 255, 255, 127);
        imagefilledrectangle($canvas, 0, 0, $width, $height, $transparent);
        imagecolortransparent($canvas, $transparent);
        imagealphablending($canvas, true);

        // copy original
        imagecopy($canvas, $resource, 0, 0, 0, 0, $width, $height);
        imagedestroy($resource);

        $resource = $canvas;

        return true;
    }
}


code:
<?php

namespace Intervention\Image\Gd;

use Intervention\Image\Exception\NotSupportedException;
use Intervention\Image\Image;

class Driver extends \Intervention\Image\AbstractDriver
{
    /**
     * Creates new instance of driver
     *
     * @param Decoder $decoder
     * @param Encoder $encoder
     */
    public function __construct(Decoder $decoder = null, Encoder $encoder = null)
    {
        if ( ! $this->coreAvailable()) {
            throw new NotSupportedException(
                "GD Library extension not available with this PHP installation."
            );
        }

        $this->decoder = $decoder ? $decoder : new Decoder;
        $this->encoder = $encoder ? $encoder : new Encoder;
    }

    /**
     * Creates new image instance
     *
     * @param  int     $width
     * @param  int     $height
     * @param  mixed   $background
     * @return \Intervention\Image\Image
     */
    public function newImage($width, $height, $background = null)
    {
        // create empty resource
        $core = imagecreatetruecolor($width, $height);
        $image = new Image(new static, $core);

        // set background color
        $background = new Color($background);
        imagefill($image->getCore(), 0, 0, $background->getInt());

        return $image;
    }

    /**
     * Reads given string into color object
     *
     * @param  string $value
     * @return AbstractColor
     */
    public function parseColor($value)
    {
        return new Color($value);
    }

    /**
     * Checks if core module installation is available
     *
     * @return boolean
     */
    protected function coreAvailable()
    {
        return (extension_loaded('gd') && function_exists('gd_info'));
    }

    /**
     * Returns clone of given core
     *
     * @return mixed
     */
    public function cloneCore($core)
    {
        $width = imagesx($core);
        $height = imagesy($core);
        $clone = imagecreatetruecolor($width, $height);
        imagealphablending($clone, false);
        imagesavealpha($clone, true);
        $transparency = imagecolorallocatealpha($clone, 0, 0, 0, 127);
        imagefill($clone, 0, 0, $transparency);

        imagecopy($clone, $core, 0, 0, 0, 0, $width, $height);

        return $clone;
    }
}

license: mit


code:
<?php

namespace Intervention\Image\Gd;

use Intervention\Image\Exception\NotSupportedException;

class Encoder extends \Intervention\Image\AbstractEncoder
{
    /**
     * Processes and returns encoded image as JPEG string
     *
     * @return string
     */
    protected function processJpeg()
    {
        ob_start();
        imagejpeg($this->image->getCore(), null, $this->quality);
        $this->image->mime = image_type_to_mime_type(IMAGETYPE_JPEG);
        $buffer = ob_get_contents();
        ob_end_clean();

        return $buffer;
    }

    /**
     * Processes and returns encoded image as PNG string
     *
     * @return string
     */
    protected function processPng()
    {
        ob_start();
        $resource = $this->image->getCore();
        imagealphablending($resource, false);
        imagesavealpha($resource, true);
        imagepng($resource, null, -1);
        $this->image->mime = image_type_to_mime_type(IMAGETYPE_PNG);
        $buffer = ob_get_contents();
        ob_end_clean();

        return $buffer;
    }

    /**
     * Processes and returns encoded image as GIF string
     *
     * @return string
     */
    protected function processGif()
    {
        ob_start();
        imagegif($this->image->getCore());
        $this->image->mime = image_type_to_mime_type(IMAGETYPE_GIF);
        $buffer = ob_get_contents();
        ob_end_clean();

        return $buffer;
    }

    protected function processWebp()
    {
        if ( ! function_exists('imagewebp')) {
            throw new NotSupportedException(
                "Webp format is not supported by PHP installation."
            );
        }

        ob_start();
        imagewebp($this->image->getCore(), null, $this->quality);
        $this->image->mime = defined('IMAGETYPE_WEBP') ? image_type_to_mime_type(IMAGETYPE_WEBP) : 'image/webp';
        $buffer = ob_get_contents();
        ob_end_clean();

        return $buffer;
    }

    /**
     * Processes and returns encoded image as TIFF string
     *
     * @return string
     */
    protected function processTiff()
    {
        throw new NotSupportedException(
            "TIFF format is not supported by Gd Driver."
        );
    }

    /**
     * Processes and returns encoded image as BMP string
     *
     * @return string
     */
    protected function processBmp()
    {
        throw new NotSupportedException(
            "BMP format is not supported by Gd Driver."
        );
    }

    /**
     * Processes and returns encoded image as ICO string
     *
     * @return string
     */
    protected function processIco()
    {
        throw new NotSupportedException(
            "ICO format is not supported by Gd Driver."
        );
    }

    /**
     * Processes and returns encoded image as PSD string
     *
     * @return string
     */
    protected function processPsd()
    {
        throw new NotSupportedException(
            "PSD format is not supported by Gd Driver."
        );
    }
}


code:
<?php

namespace Intervention\Image\Gd;

use Intervention\Image\Exception\NotSupportedException;
use Intervention\Image\Image;

class Font extends \Intervention\Image\AbstractFont
{
    /**
     * Get font size in points
     *
     * @return int
     */
    protected function getPointSize()
    {
        return intval(ceil($this->size * 0.75));
    }

    /**
     * Filter function to access internal integer font values
     *
     * @return int
     */
    private function getInternalFont()
    {
        $internalfont = is_null($this->file) ? 1 : $this->file;
        $internalfont = is_numeric($internalfont) ? $internalfont : false;

        if ( ! in_array($internalfont, [1, 2, 3, 4, 5])) {
            throw new NotSupportedException(
                sprintf('Internal GD font (%s) not available. Use only 1-5.', $internalfont)
            );
        }

        return intval($internalfont);
    }

    /**
     * Get width of an internal font character
     *
     * @return int
     */
    private function getInternalFontWidth()
    {
        return $this->getInternalFont() + 4;
    }

    /**
     * Get height of an internal font character
     *
     * @return int
     */
    private function getInternalFontHeight()
    {
        switch ($this->getInternalFont()) {
            case 1:
                return 8;

            case 2:
                return 14;

            case 3:
                return 14;

            case 4:
                return 16;

            case 5:
                return 16;
        }
    }

    /**
     * Calculates bounding box of current font setting
     *
     * @return Array
     */
    public function getBoxSize()
    {
        $box = [];

        if ($this->hasApplicableFontFile()) {

            // get bounding box with angle 0
            $box = imagettfbbox($this->getPointSize(), 0, $this->file, $this->text);

            // rotate points manually
            if ($this->angle != 0) {

                $angle = pi() * 2 - $this->angle * pi() * 2 / 360;

                for ($i=0; $i<4; $i++) {
                    $x = $box[$i * 2];
                    $y = $box[$i * 2 + 1];
                    $box[$i * 2] = cos($angle) * $x - sin($angle) * $y;
                    $box[$i * 2 + 1] = sin($angle) * $x + cos($angle) * $y;
                }
            }

            $box['width'] = intval(abs($box[4] - $box[0]));
            $box['height'] = intval(abs($box[5] - $box[1]));

        } else {

            // get current internal font size
            $width = $this->getInternalFontWidth();
            $height = $this->getInternalFontHeight();

            if (strlen($this->text) == 0) {
                // no text -> no boxsize
                $box['width'] = 0;
                $box['height'] = 0;
            } else {
                // calculate boxsize
                $box['width'] = strlen($this->text) * $width;
                $box['height'] = $height;
            }
        }

        return $box;
    }

    /**
     * Draws font to given image at given position
     *
     * @param  Image   $image
     * @param  int     $posx
     * @param  int     $posy
     * @return void
     */
    public function applyToImage(Image $image, $posx = 0, $posy = 0)
    {
        // parse text color
        $color = new Color($this->color);

        if ($this->hasApplicableFontFile()) {

            if ($this->angle != 0 || is_string($this->align) || is_string($this->valign)) {

                $box = $this->getBoxSize();

                $align = is_null($this->align) ? 'left' : strtolower($this->align);
                $valign = is_null($this->valign) ? 'bottom' : strtolower($this->valign);

                // correction on position depending on v/h alignment
                switch ($align.'-'.$valign) {

                    case 'center-top':
                        $posx = $posx - round(($box[6]+$box[4])/2);
                        $posy = $posy - round(($box[7]+$box[5])/2);
                        break;

                    case 'right-top':
                        $posx = $posx - $box[4];
                        $posy = $posy - $box[5];
                        break;

                    case 'left-top':
                        $posx = $posx - $box[6];
                        $posy = $posy - $box[7];
                        break;

                    case 'center-center':
                    case 'center-middle':
                        $posx = $posx - round(($box[0]+$box[4])/2);
                        $posy = $posy - round(($box[1]+$box[5])/2);
                        break;

                    case 'right-center':
                    case 'right-middle':
                        $posx = $posx - round(($box[2]+$box[4])/2);
                        $posy = $posy - round(($box[3]+$box[5])/2);
                        break;

                    case 'left-center':
                    case 'left-middle':
                        $posx = $posx - round(($box[0]+$box[6])/2);
                        $posy = $posy - round(($box[1]+$box[7])/2);
                        break;

                    case 'center-bottom':
                        $posx = $posx - round(($box[0]+$box[2])/2);
                        $posy = $posy - round(($box[1]+$box[3])/2);
                        break;

                    case 'right-bottom':
                        $posx = $posx - $box[2];
                        $posy = $posy - $box[3];
                        break;

                    case 'left-bottom':
                        $posx = $posx - $box[0];
                        $posy = $posy - $box[1];
                        break;
                }
            }

            // enable alphablending for imagettftext
            imagealphablending($image->getCore(), true);

            // draw ttf text
            imagettftext($image->getCore(), $this->getPointSize(), $this->angle, $posx, $posy, $color->getInt(), $this->file, $this->text);

        } else {

            // get box size
            $box = $this->getBoxSize();
            $width = $box['width'];
            $height = $box['height'];

            // internal font specific position corrections
            if ($this->getInternalFont() == 1) {
                $top_correction = 1;
                $bottom_correction = 2;
            } elseif ($this->getInternalFont() == 3) {
                $top_correction = 2;
                $bottom_correction = 4;
            } else {
                $top_correction = 3;
                $bottom_correction = 4;
            }

            // x-position corrections for horizontal alignment
            switch (strtolower($this->align)) {
                case 'center':
                    $posx = ceil($posx - ($width / 2));
                    break;

                case 'right':
                    $posx = ceil($posx - $width) + 1;
                    break;
            }

            // y-position corrections for vertical alignment
            switch (strtolower($this->valign)) {
                case 'center':
                case 'middle':
                    $posy = ceil($posy - ($height / 2));
                    break;

                case 'top':
                    $posy = ceil($posy - $top_correction);
                    break;

                default:
                case 'bottom':
                    $posy = round($posy - $height + $bottom_correction);
                    break;
            }

            // draw text
            imagestring($image->getCore(), $this->getInternalFont(), $posx, $posy, $this->text, $color->getInt());
        }
    }
}


code:
<?php

namespace Intervention\Image\Gd\Shapes;

use Intervention\Image\Image;

class CircleShape extends EllipseShape
{
    /**
     * Diameter of circle in pixels
     *
     * @var int
     */
    public $diameter = 100;

    /**
     * Create new instance of circle
     *
     * @param int $diameter
     */
    public function __construct($diameter = null)
    {
        $this->width = is_numeric($diameter) ? intval($diameter) : $this->diameter;
        $this->height = is_numeric($diameter) ? intval($diameter) : $this->diameter;
        $this->diameter = is_numeric($diameter) ? intval($diameter) : $this->diameter;
    }

    /**
     * Draw current circle on given image
     *
     * @param  Image   $image
     * @param  int     $x
     * @param  int     $y
     * @return boolean
     */
    public function applyToImage(Image $image, $x = 0, $y = 0)
    {
        return parent::applyToImage($image, $x, $y);
    }
}


code:
<?php

namespace Intervention\Image\Gd\Shapes;

use Intervention\Image\AbstractShape;
use Intervention\Image\Gd\Color;
use Intervention\Image\Image;

class EllipseShape extends AbstractShape
{
    /**
     * Width of ellipse in pixels
     *
     * @var int
     */
    public $width = 100;

    /**
     * Height of ellipse in pixels
     *
     * @var int
     */
    public $height = 100;

    /**
     * Create new ellipse instance
     *
     * @param int $width
     * @param int $height
     */
    public function __construct($width = null, $height = null)
    {
        $this->width = is_numeric($width) ? intval($width) : $this->width;
        $this->height = is_numeric($height) ? intval($height) : $this->height;
    }

    /**
     * Draw ellipse instance on given image
     *
     * @param  Image   $image
     * @param  int     $x
     * @param  int     $y
     * @return boolean
     */
    public function applyToImage(Image $image, $x = 0, $y = 0)
    {
        // parse background color
        $background = new Color($this->background);

        if ($this->hasBorder()) {
            // slightly smaller ellipse to keep 1px bordered edges clean
            imagefilledellipse($image->getCore(), $x, $y, $this->width-1, $this->height-1, $background->getInt());

            $border_color = new Color($this->border_color);
            imagesetthickness($image->getCore(), $this->border_width);

            // gd's imageellipse doesn't respect imagesetthickness so i use imagearc with 359.9 degrees here
            imagearc($image->getCore(), $x, $y, $this->width, $this->height, 0, 359.99, $border_color->getInt());
        } else {
            imagefilledellipse($image->getCore(), $x, $y, $this->width, $this->height, $background->getInt());
        }

        return true;
    }
}


code:
<?php

namespace Intervention\Image\Gd\Shapes;

use Intervention\Image\AbstractShape;
use Intervention\Image\Gd\Color;
use Intervention\Image\Image;

class LineShape extends AbstractShape
{
    /**
     * Starting point x-coordinate of line
     *
     * @var int
     */
    public $x = 0;

    /**
     * Starting point y-coordinate of line
     *
     * @var int
     */
    public $y = 0;

    /**
     * Color of line
     *
     * @var string
     */
    public $color = '#000000';

    /**
     * Width of line in pixels
     *
     * @var int
     */
    public $width = 1;

    /**
     * Create new line shape instance
     *
     * @param int $x
     * @param int $y
     */
    public function __construct($x = null, $y = null)
    {
        $this->x = is_numeric($x) ? intval($x) : $this->x;
        $this->y = is_numeric($y) ? intval($y) : $this->y;
    }

    /**
     * Set current line color
     *
     * @param  string $color
     * @return void
     */
    public function color($color)
    {
        $this->color = $color;
    }

    /**
     * Set current line width in pixels
     *
     * @param  int $width
     * @return void
     */
    public function width($width)
    {
        throw new \Intervention\Image\Exception\NotSupportedException(
            "Line width is not supported by GD driver."
        );
    }

    /**
     * Draw current instance of line to given endpoint on given image
     *
     * @param  Image   $image
     * @param  int     $x
     * @param  int     $y
     * @return boolean
     */
    public function applyToImage(Image $image, $x = 0, $y = 0)
    {
        $color = new Color($this->color);
        imageline($image->getCore(), $x, $y, $this->x, $this->y, $color->getInt());

        return true;
    }
}


code:
<?php

namespace Intervention\Image\Gd\Shapes;

use Intervention\Image\AbstractShape;
use Intervention\Image\Gd\Color;
use Intervention\Image\Image;

class PolygonShape extends AbstractShape
{
    /**
     * Array of points of polygon
     *
     * @var int
     */
    public $points;

    /**
     * Create new polygon instance
     *
     * @param array $points
     */
    public function __construct($points)
    {
        $this->points = $points;
    }

    /**
     * Draw polygon on given image
     *
     * @param  Image   $image
     * @param  int     $x
     * @param  int     $y
     * @return boolean
     */
    public function applyToImage(Image $image, $x = 0, $y = 0)
    {
        $background = new Color($this->background);
        imagefilledpolygon($image->getCore(), $this->points, intval(count($this->points) / 2), $background->getInt());

        if ($this->hasBorder()) {
            $border_color = new Color($this->border_color);
            imagesetthickness($image->getCore(), $this->border_width);
            imagepolygon($image->getCore(), $this->points, intval(count($this->points) / 2), $border_color->getInt());
        }

        return true;
    }
}


code:
<?php

namespace Intervention\Image\Gd\Shapes;

use Intervention\Image\AbstractShape;
use Intervention\Image\Gd\Color;
use Intervention\Image\Image;

class RectangleShape extends AbstractShape
{
    /**
     * X-Coordinate of top-left point
     *
     * @var int
     */
    public $x1 = 0;

    /**
     * Y-Coordinate of top-left point
     *
     * @var int
     */
    public $y1 = 0;

    /**
     * X-Coordinate of bottom-right point
     *
     * @var int
     */
    public $x2 = 0;

    /**
     * Y-Coordinate of bottom-right point
     *
     * @var int
     */
    public $y2 = 0;

    /**
     * Create new rectangle shape instance
     *
     * @param int $x1
     * @param int $y1
     * @param int $x2
     * @param int $y2
     */
    public function __construct($x1 = null, $y1 = null, $x2 = null, $y2 = null)
    {
        $this->x1 = is_numeric($x1) ? intval($x1) : $this->x1;
        $this->y1 = is_numeric($y1) ? intval($y1) : $this->y1;
        $this->x2 = is_numeric($x2) ? intval($x2) : $this->x2;
        $this->y2 = is_numeric($y2) ? intval($y2) : $this->y2;
    }

    /**
     * Draw rectangle to given image at certain position
     *
     * @param  Image   $image
     * @param  int     $x
     * @param  int     $y
     * @return boolean
     */
    public function applyToImage(Image $image, $x = 0, $y = 0)
    {
        $background = new Color($this->background);
        imagefilledrectangle($image->getCore(), $this->x1, $this->y1, $this->x2, $this->y2, $background->getInt());

        if ($this->hasBorder()) {
            $border_color = new Color($this->border_color);
            imagesetthickness($image->getCore(), $this->border_width);
            imagerectangle($image->getCore(), $this->x1, $this->y1, $this->x2, $this->y2, $border_color->getInt());
        }

        return true;
    }
}


code:
<?php

namespace Intervention\Image;

use Intervention\Image\Exception\NotWritableException;
use Intervention\Image\Exception\RuntimeException;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\StreamInterface;

/**
 * @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.
 * @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.
 * @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.
 * @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.
 * @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.
 * @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.
 * @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.
 * @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.
 * @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.
 * @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.
 * @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.
 * @method mixed                     exif(string $key = null)                                                                                Read Exif meta data from current image.
 * @method mixed                     iptc(string $key = null)                                                                                Read Iptc meta data from current image.
 * @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.
 * @method \Intervention\Image\Image flip(string $mode = 'h')                                                                                Mirror the current image horizontally or vertically by specifying the mode.
 * @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.
 * @method \Intervention\Image\Image gamma(float $correction)                                                                                Performs a gamma correction operation on the current image.
 * @method \Intervention\Image\Image greyscale()                                                                                Turns image into a greyscale version.
 * @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.
 * @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.
 * @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.
 * @method \Intervention\Image\Image invert()                                                                                Reverses all colors of the current image.
 * @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.
 * @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.
 * @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.
 * @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.
 * @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.
 * @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.
 * @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.
 * @method \Intervention\Image\Image pixel(mixed $color, int $x, int $y)                                                                                Draw a single pixel in given color on x, y position.
 * @method \Intervention\Image\Image pixelate(int $size)                                                                                Applies a pixelation effect to the current image with a given size of pixels.
 * @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.
 * @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.
 * @method \Intervention\Image\Image reset(string $name = 'default')                                                                                Resets all of the modifications to a state saved previously by backup under an optional name.
 * @method \Intervention\Image\Image resize(int $width = null, 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.
 * @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.
 * @method mixed                     response(string $format = null, int $quality = 90)                                                                               Sends HTTP response with current image in given format and quality.
 * @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.
 * @method \Intervention\Image\Image sharpen(int $amount = 10)                                                                                Sharpen current image with an optional amount. Use values between 0 and 100.
 * @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.
 * @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.
 * @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.
 * @method StreamInterface           stream(string $format = null, int $quality = 90)                                                                                Build PSR-7 compatible StreamInterface with current image in given format and quality.
 * @method ResponseInterface         psrResponse(string $format = null, int $quality = 90)                                                                            Build PSR-7 compatible ResponseInterface with current image in given format and quality.
 */
class Image extends File
{
    /**
     * Instance of current image driver
     *
     * @var AbstractDriver
     */
    protected $driver;

    /**
     * Image resource/object of current image processor
     *
     * @var mixed
     */
    protected $core;

    /**
     * Array of Image resource backups of current image processor
     *
     * @var array
     */
    protected $backups = [];

    /**
     * Last image encoding result
     *
     * @var string
     */
    public $encoded = '';

    /**
     * Creates a new Image instance
     *
     * @param AbstractDriver $driver
     * @param mixed  $core
     */
    public function __construct(AbstractDriver $driver = null, $core = null)
    {
        $this->driver = $driver;
        $this->core = $core;
    }

    /**
     * Magic method to catch all image calls
     * usually any AbstractCommand
     *
     * @param  string $name
     * @param  Array  $arguments
     * @return mixed
     */
    public function __call($name, $arguments)
    {
        $command = $this->driver->executeCommand($this, $name, $arguments);
        return $command->hasOutput() ? $command->getOutput() : $this;
    }

    /**
     * Starts encoding of current image
     *
     * @param  string  $format
     * @param  int     $quality
     * @return \Intervention\Image\Image
     */
    public function encode($format = null, $quality = 90)
    {
        return $this->driver->encode($this, $format, $quality);
    }

    /**
     * Saves encoded image in filesystem
     *
     * @param  string  $path
     * @param  int     $quality
     * @param  string  $format
     * @return \Intervention\Image\Image
     */
    public function save($path = null, $quality = null, $format = null)
    {
        $path = is_null($path) ? $this->basePath() : $path;

        if (is_null($path)) {
            throw new NotWritableException(
                "Can't write to undefined path."
            );
        }

        if ($format === null) {
            $format = pathinfo($path, PATHINFO_EXTENSION);
        }

        $data = $this->encode($format, $quality);
        $saved = @file_put_contents($path, $data);

        if ($saved === false) {
            throw new NotWritableException(
                "Can't write image data to path ({$path})"
            );
        }

        // set new file info
        $this->setFileInfoFromPath($path);

        return $this;
    }

    /**
     * Runs a given filter on current image
     *
     * @param  FiltersFilterInterface $filter
     * @return \Intervention\Image\Image
     */
    public function filter(Filters\FilterInterface $filter)
    {
        return $filter->applyFilter($this);
    }

    /**
     * Returns current image driver
     *
     * @return \Intervention\Image\AbstractDriver
     */
    public function getDriver()
    {
        return $this->driver;
    }

    /**
     * Sets current image driver
     * @param AbstractDriver $driver
     */
    public function setDriver(AbstractDriver $driver)
    {
        $this->driver = $driver;

        return $this;
    }

    /**
     * Returns current image resource/obj
     *
     * @return mixed
     */
    public function getCore()
    {
        return $this->core;
    }

    /**
     * Sets current image resource
     *
     * @param mixed $core
     */
    public function setCore($core)
    {
        $this->core = $core;

        return $this;
    }

    /**
     * Returns current image backup
     *
     * @param string $name
     * @return mixed
     */
    public function getBackup($name = null)
    {
        $name = is_null($name) ? 'default' : $name;

        if ( ! $this->backupExists($name)) {
            throw new RuntimeException(
                "Backup with name ({$name}) not available. Call backup() before reset()."
            );
        }

        return $this->backups[$name];
    }

    /**
     * Returns all backups attached to image
     *
     * @return array
     */
    public function getBackups()
    {
        return $this->backups;
    }

    /**
     * Sets current image backup
     *
     * @param mixed  $resource
     * @param string $name
     * @return self
     */
    public function setBackup($resource, $name = null)
    {
        $name = is_null($name) ? 'default' : $name;

        $this->backups[$name] = $resource;

        return $this;
    }

    /**
     * Checks if named backup exists
     *
     * @param  string $name
     * @return bool
     */
    private function backupExists($name)
    {
        return array_key_exists($name, $this->backups);
    }

    /**
     * Checks if current image is already encoded
     *
     * @return boolean
     */
    public function isEncoded()
    {
        return ! empty($this->encoded);
    }

    /**
     * Returns encoded image data of current image
     *
     * @return string
     */
    public function getEncoded()
    {
        return $this->encoded;
    }

    /**
     * Sets encoded image buffer
     *
     * @param string $value
     */
    public function setEncoded($value)
    {
        $this->encoded = $value;

        return $this;
    }

    /**
     * Calculates current image width
     *
     * @return int
     */
    public function getWidth()
    {
        return $this->getSize()->width;
    }

    /**
     * Alias of getWidth()
     *
     * @return int
     */
    public function width()
    {
        return $this->getWidth();
    }

    /**
     * Calculates current image height
     *
     * @return int
     */
    public function getHeight()
    {
        return $this->getSize()->height;
    }

    /**
     * Alias of getHeight
     *
     * @return int
     */
    public function height()
    {
        return $this->getHeight();
    }

    /**
     * Reads mime type
     *
     * @return string
     */
    public function mime()
    {
        return $this->mime;
    }

    /**
     * Returns encoded image data in string conversion
     *
     * @return string
     */
    public function __toString()
    {
        return $this->encoded;
    }

    /**
     * Cloning an image
     */
    public function __clone()
    {
        $this->core = $this->driver->cloneCore($this->core);
    }
}


code:
<?php

namespace Intervention\Image;

use Closure;
use Intervention\Image\Exception\MissingDependencyException;
use Intervention\Image\Exception\NotSupportedException;

class ImageManager
{
    /**
     * Config
     *
     * @var array
     */
    public $config = [
        'driver' => 'gd'
    ];

    /**
     * Creates new instance of Image Manager
     *
     * @param array $config
     */
    public function __construct(array $config = [])
    {
        $this->checkRequirements();
        $this->configure($config);
    }

    /**
     * Overrides configuration settings
     *
     * @param array $config
     *
     * @return self
     */
    public function configure(array $config = [])
    {
        $this->config = array_replace($this->config, $config);

        return $this;
    }

    /**
     * Initiates an Image instance from different input types
     *
     * @param  mixed $data
     *
     * @return \Intervention\Image\Image
     */
    public function make($data)
    {
        return $this->createDriver()->init($data);
    }

    /**
     * Creates an empty image canvas
     *
     * @param  int   $width
     * @param  int   $height
     * @param  mixed $background
     *
     * @return \Intervention\Image\Image
     */
    public function canvas($width, $height, $background = null)
    {
        return $this->createDriver()->newImage($width, $height, $background);
    }

    /**
     * Create new cached image and run callback
     * (requires additional package intervention/imagecache)
     *
     * @param Closure $callback
     * @param int     $lifetime
     * @param boolean $returnObj
     *
     * @return Image
     */
    public function cache(Closure $callback, $lifetime = null, $returnObj = false)
    {
        if (class_exists('Intervention\\Image\\ImageCache')) {
            // create imagecache
            $imagecache = new ImageCache($this);

            // run callback
            if (is_callable($callback)) {
                $callback($imagecache);
            }

            return $imagecache->get($lifetime, $returnObj);
        }

        throw new MissingDependencyException(
            "Please install package intervention/imagecache before running this function."
        );
    }

    /**
     * Creates a driver instance according to config settings
     *
     * @return \Intervention\Image\AbstractDriver
     */
    private function createDriver()
    {
        if (is_string($this->config['driver'])) {
            $drivername = ucfirst($this->config['driver']);
            $driverclass = sprintf('Intervention\\Image\\%s\\Driver', $drivername);

            if (class_exists($driverclass)) {
                return new $driverclass;
            }

            throw new NotSupportedException(
                "Driver ({$drivername}) could not be instantiated."
            );
        }

        if ($this->config['driver'] instanceof AbstractDriver) {
            return $this->config['driver'];
        }

        throw new NotSupportedException(
            "Unknown driver type."
        );
    }

    /**
     * Check if all requirements are available
     *
     * @return void
     */
    private function checkRequirements()
    {
        if ( ! function_exists('finfo_buffer')) {
            throw new MissingDependencyException(
                "PHP Fileinfo extension must be installed/enabled to use Intervention Image."
            );
        }
    }
}


code:
<?php

namespace Intervention\Image;

use Closure;

class ImageManagerStatic
{
    /**
     * Instance of Intervention\Image\ImageManager
     *
     * @var ImageManager
     */
    public static $manager;

    /**
     * Creates a new instance
     *
     * @param ImageManager $manager
     */
    public function __construct(ImageManager $manager = null)
    {
        self::$manager = $manager ? $manager : new ImageManager;
    }

    /**
     * Get or create new ImageManager instance
     *
     * @return ImageManager
     */
    public static function getManager()
    {
        return self::$manager ? self::$manager : new ImageManager;
    }

    /**
     * Statically create new custom configured image manager
     *
     * @param  array $config
     *
     * @return ImageManager
     */
    public static function configure(array $config = [])
    {
        return self::$manager = self::getManager()->configure($config);
    }

    /**
     * Statically initiates an Image instance from different input types
     *
     * @param  mixed $data
     *
     * @return \Intervention\Image\Image
     * @throws \Intervention\Image\Exception\NotReadableException
     */
    public static function make($data)
    {
        return self::getManager()->make($data);
    }

    /**
     * Statically creates an empty image canvas
     *
     * @param  int   $width
     * @param  int   $height
     * @param  mixed $background
     *
     * @return \Intervention\Image\Image
     */
    public static function canvas($width, $height, $background = null)
    {
        return self::getManager()->canvas($width, $height, $background);
    }

    /**
     * Create new cached image and run callback statically
     *
     * @param  Closure  $callback
     * @param  int      $lifetime
     * @param  boolean  $returnObj
     *
     * @return mixed
     */
    public static function cache(Closure $callback, $lifetime = null, $returnObj = false)
    {
        return self::getManager()->cache($callback, $lifetime, $returnObj);
    }
}


code:
<?php

namespace Intervention\Image;

use Illuminate\Support\ServiceProvider;
use Laravel\Lumen\Application as LumenApplication;
use Illuminate\Foundation\Application as IlluminateApplication;

class ImageServiceProvider extends ServiceProvider
{
    /**
     * Indicates if loading of the provider is deferred.
     *
     * @var bool
     */
    protected $defer = false;

    /**
     * Actual provider
     *
     * @var \Illuminate\Support\ServiceProvider
     */
    protected $provider;

    /**
     * Create a new service provider instance.
     *
     * @param  \Illuminate\Contracts\Foundation\Application  $app
     * @return void
     */
    public function __construct($app)
    {
        parent::__construct($app);

        $this->provider = $this->getProvider();
    }

    /**
     * Bootstrap the application events.
     *
     * @return void
     */
    public function boot()
    {
        if (method_exists($this->provider, 'boot')) {
            return $this->provider->boot();
        }
    }

    /**
     * Register the service provider.
     *
     * @return void
     */
    public function register()
    {
        return $this->provider->register();
    }

    /**
     * Return ServiceProvider according to Laravel version
     *
     * @return \Intervention\Image\Provider\ProviderInterface
     */
    private function getProvider()
    {
        if ($this->app instanceof LumenApplication) {
            $provider = '\Intervention\Image\ImageServiceProviderLumen';
        } elseif (version_compare(IlluminateApplication::VERSION, '5.0', '<')) {
            $provider = '\Intervention\Image\ImageServiceProviderLaravel4';
        } else {
            $provider = '\Intervention\Image\ImageServiceProviderLaravel5';
        }

        return new $provider($this->app);
    }

    /**
     * Get the services provided by the provider.
     *
     * @return array
     */
    public function provides()
    {
        return ['image'];
    }
}


code:
<?php

namespace Intervention\Image;

use Illuminate\Support\ServiceProvider;
use Illuminate\Http\Response as IlluminateResponse;

class ImageServiceProviderLaravel4 extends ServiceProvider
{
    /**
     * Bootstrap the application events.
     *
     * @return void
     */
    public function boot()
    {
        $this->package('intervention/image');

        // try to create imagecache route only if imagecache is present
        if (class_exists('Intervention\\Image\\ImageCache')) {

            $app = $this->app;

            // load imagecache config
            $app['config']->package('intervention/imagecache', __DIR__.'/../../../../imagecache/src/config', 'imagecache');
            $config = $app['config'];

            // create dynamic manipulation route
            if (is_string($config->get('imagecache::route'))) {

                // add original to route templates
                $config->set('imagecache::templates.original', null);

                // setup image manipulator route
                $app['router']->get($config->get('imagecache::route').'/{template}/{filename}', ['as' => 'imagecache', function ($template, $filename) use ($app, $config) {

                    // disable session cookies for image route
                    $app['config']->set('session.driver', 'array');

                    // find file
                    foreach ($config->get('imagecache::paths') as $path) {
                        // don't allow '..' in filenames
                        $image_path = $path.'/'.str_replace('..', '', $filename);
                        if (file_exists($image_path) && is_file($image_path)) {
                            break;
                        } else {
                            $image_path = false;
                        }
                    }

                    // abort if file not found
                    if ($image_path === false) {
                        $app->abort(404);
                    }

                    // define template callback
                    $callback = $config->get("imagecache::templates.{$template}");

                    if (is_callable($callback) || class_exists($callback)) {

                        // image manipulation based on callback
                        $content = $app['image']->cache(function ($image) use ($image_path, $callback) {

                            switch (true) {
                                case is_callable($callback):
                                    return $callback($image->make($image_path));
                                    break;

                                case class_exists($callback):
                                    return $image->make($image_path)->filter(new $callback);
                                    break;
                            }

                        }, $config->get('imagecache::lifetime'));

                    } else {

                        // get original image file contents
                        $content = file_get_contents($image_path);
                    }

                    // define mime type
                    $mime = finfo_buffer(finfo_open(FILEINFO_MIME_TYPE), $content);

                    // return http response
                    return new IlluminateResponse($content, 200, [
                        'Content-Type' => $mime,
                        'Cache-Control' => 'max-age='.($config->get('imagecache::lifetime')*60).', public',
                        'Etag' => md5($content)
                    ]);

                }])->where(['template' => join('|', array_keys($config->get('imagecache::templates'))), 'filename' => '[ \w\\.\\/\\-]+']);
            }
        }
    }

    /**
     * Register the service provider.
     *
     * @return void
     */
    public function register()
    {
        $app = $this->app;

        $app['image'] = $app->share(function ($app) {
            return new ImageManager($app['config']->get('image::config'));
        });

        $app->alias('image', 'Intervention\Image\ImageManager');
    }
}


code:
<?php

namespace Intervention\Image;

use Illuminate\Support\ServiceProvider;

class ImageServiceProviderLaravel5 extends ServiceProvider
{
    /**
     * Determines if Intervention Imagecache is installed
     *
     * @return boolean
     */
    private function cacheIsInstalled()
    {
        return class_exists('Intervention\\Image\\ImageCache');
    }

    /**
     * Bootstrap the application events.
     *
     * @return void
     */
    public function boot()
    {
        $this->publishes([
            __DIR__.'/../../config/config.php' => config_path('image.php')
        ]);

        // setup intervention/imagecache if package is installed
        $this->cacheIsInstalled() ? $this->bootstrapImageCache() : null;
    }

    /**
     * Register the service provider.
     *
     * @return void
     */
    public function register()
    {
        $app = $this->app;

        // merge default config
        $this->mergeConfigFrom(
            __DIR__.'/../../config/config.php',
            'image'
        );

        // create image
        $app->singleton('image', function ($app) {
            return new ImageManager($app['config']->get('image'));
        });

        $app->alias('image', 'Intervention\Image\ImageManager');
    }

    /**
     * Bootstrap imagecache
     *
     * @return void
     */
    protected function bootstrapImageCache()
    {
        $app = $this->app;
        $config = __DIR__.'/../../../../imagecache/src/config/config.php';

        $this->publishes([
            $config => config_path('imagecache.php')
        ]);

        // merge default config
        $this->mergeConfigFrom(
            $config,
            'imagecache'
        );

        // imagecache route
        if (is_string(config('imagecache.route'))) {

            $filename_pattern = '[ \w\\.\\/\\-\\@\(\)]+';

            // route to access template applied image file
            $app['router']->get(config('imagecache.route').'/{template}/{filename}', [
                'uses' => 'Intervention\Image\ImageCacheController@getResponse',
                'as' => 'imagecache'
            ])->where(['filename' => $filename_pattern]);
        }
    }
}


code:
<?php

namespace Intervention\Image;

use League\Container\ServiceProvider\AbstractServiceProvider;

class ImageServiceProviderLeague extends AbstractServiceProvider
{
    /**
     * @var array $config
     */
    protected $config;

    /**
     * @var array $provides
     */
    protected $provides = [
        'Intervention\Image\ImageManager'
    ];

    /**
     * Constructor.
     *
     * @param array $config
     */
    public function __construct($config = [])
    {
        $this->config = $config;
    }

    /**
     * Register the server provider.
     *
     * @return void
     */
    public function register()
    {
        $this->getContainer()->share('Intervention\Image\ImageManager', function () {
            return new ImageManager($this->config);
        });
    }
}


code:
<?php

namespace Intervention\Image;

use Illuminate\Support\ServiceProvider;

class ImageServiceProviderLumen extends ServiceProvider
{
    /**
     * Register the service provider.
     *
     * @return void
     */
    public function register()
    {
        $app = $this->app;

        // merge default config
        $this->mergeConfigFrom(
          __DIR__.'/../../config/config.php',
          'image'
        );

        // set configuration
        $app->configure('image');

        // create image
        $app->singleton('image',function ($app) {
            return new ImageManager($app['config']->get('image'));
        });

        $app->alias('image', 'Intervention\Image\ImageManager');
    }
}


code:
<?php

namespace Intervention\Image\Imagick;

use Intervention\Image\AbstractColor;

class Color extends AbstractColor
{
    /**
     * ImagickPixel containing current color information
     *
     * @var \ImagickPixel
     */
    public $pixel;

    /**
     * Initiates color object from integer
     *
     * @param  int $value
     * @return \Intervention\Image\AbstractColor
     */
    public function initFromInteger($value)
    {
        $a = ($value >> 24) & 0xFF;
        $r = ($value >> 16) & 0xFF;
        $g = ($value >> 8) & 0xFF;
        $b = $value & 0xFF;
        $a = $this->rgb2alpha($a);

        $this->setPixel($r, $g, $b, $a);
    }

    /**
     * Initiates color object from given array
     *
     * @param  array $value
     * @return \Intervention\Image\AbstractColor
     */
    public function initFromArray($array)
    {
        $array = array_values($array);

        if (count($array) == 4) {

            // color array with alpha value
            list($r, $g, $b, $a) = $array;

        } elseif (count($array) == 3) {

            // color array without alpha value
            list($r, $g, $b) = $array;
            $a = 1;
        }

        $this->setPixel($r, $g, $b, $a);
    }

    /**
     * Initiates color object from given string
     *
     * @param  string $value
     *
     * @return \Intervention\Image\AbstractColor
     */
    public function initFromString($value)
    {
        if ($color = $this->rgbaFromString($value)) {
            $this->setPixel($color[0], $color[1], $color[2], $color[3]);
        }
    }

    /**
     * Initiates color object from given ImagickPixel object
     *
     * @param  ImagickPixel $value
     *
     * @return \Intervention\Image\AbstractColor
     */
    public function initFromObject($value)
    {
        if (is_a($value, '\ImagickPixel')) {
            $this->pixel = $value;
        }
    }

    /**
     * Initiates color object from given R, G and B values
     *
     * @param  int $r
     * @param  int $g
     * @param  int $b
     *
     * @return \Intervention\Image\AbstractColor
     */
    public function initFromRgb($r, $g, $b)
    {
        $this->setPixel($r, $g, $b);
    }

    /**
     * Initiates color object from given R, G, B and A values
     *
     * @param  int     $r
     * @param  int     $g
     * @param  int     $b
     * @param  float   $a
     *
     * @return \Intervention\Image\AbstractColor
     */
    public function initFromRgba($r, $g, $b, $a)
    {
        $this->setPixel($r, $g, $b, $a);
    }

    /**
     * Calculates integer value of current color instance
     *
     * @return int
     */
    public function getInt()
    {
        $r = $this->getRedValue();
        $g = $this->getGreenValue();
        $b = $this->getBlueValue();
        $a = intval(round($this->getAlphaValue() * 255));

        return intval(($a << 24) + ($r << 16) + ($g << 8) + $b);
    }

    /**
     * Calculates hexadecimal value of current color instance
     *
     * @param  string $prefix
     *
     * @return string
     */
    public function getHex($prefix = '')
    {
        return sprintf('%s%02x%02x%02x', $prefix,
            $this->getRedValue(),
            $this->getGreenValue(),
            $this->getBlueValue()
        );
    }

    /**
     * Calculates RGB(A) in array format of current color instance
     *
     * @return array
     */
    public function getArray()
    {
        return [
            $this->getRedValue(),
            $this->getGreenValue(),
            $this->getBlueValue(),
            $this->getAlphaValue()
        ];
    }

    /**
     * Calculates RGBA in string format of current color instance
     *
     * @return string
     */
    public function getRgba()
    {
        return sprintf('rgba(%d, %d, %d, %.2F)',
            $this->getRedValue(),
            $this->getGreenValue(),
            $this->getBlueValue(),
            $this->getAlphaValue()
        );
    }

    /**
     * Determines if current color is different from given color
     *
     * @param  AbstractColor $color
     * @param  int           $tolerance
     * @return boolean
     */
    public function differs(AbstractColor $color, $tolerance = 0)
    {
        $color_tolerance = round($tolerance * 2.55);
        $alpha_tolerance = round($tolerance);

        $delta = [
            'r' => abs($color->getRedValue() - $this->getRedValue()),
            'g' => abs($color->getGreenValue() - $this->getGreenValue()),
            'b' => abs($color->getBlueValue() - $this->getBlueValue()),
            'a' => abs($color->getAlphaValue() - $this->getAlphaValue())
        ];

        return (
            $delta['r'] > $color_tolerance or
            $delta['g'] > $color_tolerance or
            $delta['b'] > $color_tolerance or
            $delta['a'] > $alpha_tolerance
        );
    }

    /**
     * Returns RGB red value of current color
     *
     * @return int
     */
    public function getRedValue()
    {
        return intval(round($this->pixel->getColorValue(\Imagick::COLOR_RED) * 255));
    }

    /**
     * Returns RGB green value of current color
     *
     * @return int
     */
    public function getGreenValue()
    {
        return intval(round($this->pixel->getColorValue(\Imagick::COLOR_GREEN) * 255));
    }

    /**
     * Returns RGB blue value of current color
     *
     * @return int
     */
    public function getBlueValue()
    {
        return intval(round($this->pixel->getColorValue(\Imagick::COLOR_BLUE) * 255));
    }

    /**
     * Returns RGB alpha value of current color
     *
     * @return float
     */
    public function getAlphaValue()
    {
        return round($this->pixel->getColorValue(\Imagick::COLOR_ALPHA), 2);
    }

    /**
     * Initiates ImagickPixel from given RGBA values
     *
     * @return \ImagickPixel
     */
    private function setPixel($r, $g, $b, $a = null)
    {
        $a = is_null($a) ? 1 : $a;

        return $this->pixel = new \ImagickPixel(
            sprintf('rgba(%d, %d, %d, %.2F)', $r, $g, $b, $a)
        );
    }

    /**
     * Returns current color as ImagickPixel
     *
     * @return \ImagickPixel
     */
    public function getPixel()
    {
        return $this->pixel;
    }

    /**
     * Calculates RGA integer alpha value into float value
     *
     * @param  int $value
     * @return float
     */
    private function rgb2alpha($value)
    {
        // (255 -> 1.0) / (0 -> 0.0)
        return (float) round($value/255, 2);
    }

}


code:
<?php

namespace Intervention\Image\Imagick\Commands;

use Intervention\Image\Commands\AbstractCommand;

class BackupCommand extends AbstractCommand
{
    /**
     * Saves a backups of current state of image core
     *
     * @param  \Intervention\Image\Image $image
     * @return boolean
     */
    public function execute($image)
    {
        $backupName = $this->argument(0)->value();

        // clone current image resource
        $clone = clone $image;
        $image->setBackup($clone->getCore(), $backupName);

        return true;
    }
}


code:
<?php

namespace Intervention\Image\Imagick\Commands;

use Intervention\Image\Commands\AbstractCommand;

class BlurCommand extends AbstractCommand
{
    /**
     * Applies blur effect on image
     *
     * @param  \Intervention\Image\Image $image
     * @return boolean
     */
    public function execute($image)
    {
        $amount = $this->argument(0)->between(0, 100)->value(1);

        return $image->getCore()->blurImage(1 * $amount, 0.5 * $amount);
    }
}


code:
<?php

namespace Intervention\Image\Imagick\Commands;

use Intervention\Image\Commands\AbstractCommand;

class BrightnessCommand extends AbstractCommand
{
    /**
     * Changes image brightness
     *
     * @param  \Intervention\Image\Image $image
     * @return boolean
     */
    public function execute($image)
    {
        $level = $this->argument(0)->between(-100, 100)->required()->value();

        return $image->getCore()->modulateImage(100 + $level, 100, 100);
    }
}


code:
<?php

namespace Intervention\Image\Imagick\Commands;

use Intervention\Image\Commands\AbstractCommand;

class ColorizeCommand extends AbstractCommand
{
    /**
     * Changes balance of different RGB color channels
     *
     * @param  \Intervention\Image\Image $image
     * @return boolean
     */
    public function execute($image)
    {
        $red = $this->argument(0)->between(-100, 100)->required()->value();
        $green = $this->argument(1)->between(-100, 100)->required()->value();
        $blue = $this->argument(2)->between(-100, 100)->required()->value();

        // normalize colorize levels
        $red = $this->normalizeLevel($red);
        $green = $this->normalizeLevel($green);
        $blue = $this->normalizeLevel($blue);

        $qrange = $image->getCore()->getQuantumRange();

        // apply
        $image->getCore()->levelImage(0, $red, $qrange['quantumRangeLong'], \Imagick::CHANNEL_RED);
        $image->getCore()->levelImage(0, $green, $qrange['quantumRangeLong'], \Imagick::CHANNEL_GREEN);
        $image->getCore()->levelImage(0, $blue, $qrange['quantumRangeLong'], \Imagick::CHANNEL_BLUE);

        return true;
    }

    private function normalizeLevel($level)
    {
        if ($level > 0) {
            return $level/5;
        } else {
            return ($level+100)/100;
        }
    }
}


code:
<?php

namespace Intervention\Image\Imagick\Commands;

use Intervention\Image\Commands\AbstractCommand;

class ContrastCommand extends AbstractCommand
{
    /**
     * Changes contrast of image
     *
     * @param  \Intervention\Image\Image $image
     * @return boolean
     */
    public function execute($image)
    {
        $level = $this->argument(0)->between(-100, 100)->required()->value();

        return $image->getCore()->sigmoidalContrastImage($level > 0, $level / 4, 0);
    }
}


code:
<?php

namespace Intervention\Image\Imagick\Commands;

use Intervention\Image\Commands\AbstractCommand;
use Intervention\Image\Exception\InvalidArgumentException;
use Intervention\Image\Point;
use Intervention\Image\Size;

class CropCommand extends AbstractCommand
{
    /**
     * Crop an image instance
     *
     * @param  \Intervention\Image\Image $image
     * @return boolean
     */
    public function execute($image)
    {
        $width = $this->argument(0)->type('digit')->required()->value();
        $height = $this->argument(1)->type('digit')->required()->value();
        $x = $this->argument(2)->type('digit')->value();
        $y = $this->argument(3)->type('digit')->value();

        if (is_null($width) || is_null($height)) {
            throw new InvalidArgumentException(
                "Width and height of cutout needs to be defined."
            );
        }

        $cropped = new Size($width, $height);
        $position = new Point($x, $y);

        // align boxes
        if (is_null($x) && is_null($y)) {
            $position = $image->getSize()->align('center')->relativePosition($cropped->align('center'));
        }

        // crop image core
        $image->getCore()->cropImage($cropped->width, $cropped->height, $position->x, $position->y);
        $image->getCore()->setImagePage(0,0,0,0);

        return true;
    }
}


code:
<?php

namespace Intervention\Image\Imagick\Commands;

use Intervention\Image\Commands\AbstractCommand;

class DestroyCommand extends AbstractCommand
{
    /**
     * Destroys current image core and frees up memory
     *
     * @param  \Intervention\Image\Image $image
     * @return boolean
     */
    public function execute($image)
    {
        // destroy image core
        $image->getCore()->clear();

        // destroy backups
        foreach ($image->getBackups() as $backup) {
            $backup->clear();
        }

        return true;
    }
}


code:
<?php

namespace Intervention\Image\Imagick\Commands;

use Intervention\Image\Commands\ExifCommand as BaseCommand;
use Intervention\Image\Exception\NotSupportedException;

class ExifCommand extends BaseCommand
{
    /**
     * Prefer extension or not
     *
     * @var bool
     */
    private $preferExtension = true;

    /**
     *
     */
    public function dontPreferExtension() {
        $this->preferExtension = false;
    }

    /**
     * Read Exif data from the given image
     *
     * @param  \Intervention\Image\Image $image
     * @return boolean
     */
    public function execute($image)
    {
        if ($this->preferExtension && function_exists('exif_read_data')) {
            return parent::execute($image);
        }

        $core = $image->getCore();

        if ( ! method_exists($core, 'getImageProperties')) {
            throw new NotSupportedException(
                "Reading Exif data is not supported by this PHP installation."
            );
        }

        $requestedKey = $this->argument(0)->value();
        if ($requestedKey !== null) {
            $this->setOutput($core->getImageProperty('exif:' . $requestedKey));
            return true;
        }

        $exif = [];
        $properties = $core->getImageProperties();
        foreach ($properties as $key => $value) {
            if (substr($key, 0, 5) !== 'exif:') {
                continue;
            }

            $exif[substr($key, 5)] = $value;
        }

        $this->setOutput($exif);
        return true;
    }
}


code:
<?php

namespace Intervention\Image\Imagick\Commands;

use Intervention\Image\Commands\AbstractCommand;
use Intervention\Image\Exception\NotReadableException;
use Intervention\Image\Image;
use Intervention\Image\Imagick\Color;
use Intervention\Image\Imagick\Decoder;

class FillCommand extends AbstractCommand
{
    /**
     * Fills image with color or pattern
     *
     * @param  \Intervention\Image\Image $image
     * @return boolean
     */
    public function execute($image)
    {
        $filling = $this->argument(0)->value();
        $x = $this->argument(1)->type('digit')->value();
        $y = $this->argument(2)->type('digit')->value();

        $imagick = $image->getCore();

        try {
            // set image filling
            $source = new Decoder;
            $filling = $source->init($filling);

        } catch (NotReadableException $e) {

            // set solid color filling
            $filling = new Color($filling);
        }

        // flood fill if coordinates are set
        if (is_int($x) && is_int($y)) {

            // flood fill with texture
            if ($filling instanceof Image) {

                // create tile
                $tile = clone $image->getCore();

                // mask away color at position
                $tile->transparentPaintImage($tile->getImagePixelColor($x, $y), 0, 0, false);

                // create canvas
                $canvas = clone $image->getCore();

                // fill canvas with texture
                $canvas = $canvas->textureImage($filling->getCore());

                // merge canvas and tile
                $canvas->compositeImage($tile, \Imagick::COMPOSITE_DEFAULT, 0, 0);

                // replace image core
                $image->setCore($canvas);

            // flood fill with color
            } elseif ($filling instanceof Color) {

                // create canvas with filling
                $canvas = new \Imagick;
                $canvas->newImage($image->getWidth(), $image->getHeight(), $filling->getPixel(), 'png');

                // create tile to put on top
                $tile = clone $image->getCore();

                // mask away color at pos.
                $tile->transparentPaintImage($tile->getImagePixelColor($x, $y), 0, 0, false);

                // save alpha channel of original image
                $alpha = clone $image->getCore();

                // merge original with canvas and tile
                $image->getCore()->compositeImage($canvas, \Imagick::COMPOSITE_DEFAULT, 0, 0);
                $image->getCore()->compositeImage($tile, \Imagick::COMPOSITE_DEFAULT, 0, 0);

                // restore alpha channel of original image
                $image->getCore()->compositeImage($alpha, \Imagick::COMPOSITE_COPYOPACITY, 0, 0);
            }

        } else {

            if ($filling instanceof Image) {

                // fill whole image with texture
                $image->setCore($image->getCore()->textureImage($filling->getCore()));

            } elseif ($filling instanceof Color) {

                // fill whole image with color
                $draw = new \ImagickDraw();
                $draw->setFillColor($filling->getPixel());
                $draw->rectangle(0, 0, $image->getWidth(), $image->getHeight());
                $image->getCore()->drawImage($draw);
            }
        }

        return true;
    }
}


code:
<?php

namespace Intervention\Image\Imagick\Commands;

use Intervention\Image\Commands\AbstractCommand;
use Intervention\Image\Size;

class FitCommand extends AbstractCommand
{
    /**
     * Crops and resized an image at the same time
     *
     * @param  \Intervention\Image\Image $image
     * @return boolean
     */
    public function execute($image)
    {
        $width = $this->argument(0)->type('digit')->required()->value();
        $height = $this->argument(1)->type('digit')->value($width);
        $constraints = $this->argument(2)->type('closure')->value();
        $position = $this->argument(3)->type('string')->value('center');

        // calculate size
        $cropped = $image->getSize()->fit(new Size($width, $height), $position);
        $resized = clone $cropped;
        $resized = $resized->resize($width, $height, $constraints);

        // crop image
        $image->getCore()->cropImage(
            $cropped->width,
            $cropped->height,
            $cropped->pivot->x,
            $cropped->pivot->y
        );

        // resize image
        $image->getCore()->scaleImage($resized->getWidth(), $resized->getHeight());
        $image->getCore()->setImagePage(0,0,0,0);

        return true;
    }
}


code:
<?php

namespace Intervention\Image\Imagick\Commands;

use Intervention\Image\Commands\AbstractCommand;

class FlipCommand extends AbstractCommand
{
    /**
     * Mirrors an image
     *
     * @param  \Intervention\Image\Image $image
     * @return boolean
     */
    public function execute($image)
    {
        $mode = $this->argument(0)->value('h');

        if (in_array(strtolower($mode), [2, 'v', 'vert', 'vertical'])) {
            // flip vertical
            return $image->getCore()->flipImage();
        } else {
            // flip horizontal
            return $image->getCore()->flopImage();
        }
    }
}


code:
<?php

namespace Intervention\Image\Imagick\Commands;

use Intervention\Image\Commands\AbstractCommand;

class GammaCommand extends AbstractCommand
{
    /**
     * Applies gamma correction to a given image
     *
     * @param  \Intervention\Image\Image $image
     * @return boolean
     */
    public function execute($image)
    {
        $gamma = $this->argument(0)->type('numeric')->required()->value();

        return $image->getCore()->gammaImage($gamma);
    }
}


code:
<?php

namespace Intervention\Image\Imagick\Commands;

use Intervention\Image\Commands\AbstractCommand;
use Intervention\Image\Size;

class GetSizeCommand extends AbstractCommand
{
    /**
     * Reads size of given image instance in pixels
     *
     * @param  \Intervention\Image\Image $image
     * @return boolean
     */
    public function execute($image)
    {
        /** @var \Imagick $core */
        $core = $image->getCore();

        $this->setOutput(new Size(
            $core->getImageWidth(),
            $core->getImageHeight()
        ));

        return true;
    }
}


code:
<?php

namespace Intervention\Image\Imagick\Commands;

use Intervention\Image\Commands\AbstractCommand;

class GreyscaleCommand extends AbstractCommand
{
    /**
     * Turns an image into a greyscale version
     *
     * @param  \Intervention\Image\Image $image
     * @return boolean
     */
    public function execute($image)
    {
        return $image->getCore()->modulateImage(100, 0, 100);
    }
}


code:
<?php

namespace Intervention\Image\Imagick\Commands;

class HeightenCommand extends ResizeCommand
{
    /**
     * Resize image proportionally to given height
     *
     * @param  \Intervention\Image\Image $image
     * @return boolean
     */
    public function execute($image)
    {
        $height = $this->argument(0)->type('digit')->required()->value();
        $additionalConstraints = $this->argument(1)->type('closure')->value();

        $this->arguments[0] = null;
        $this->arguments[1] = $height;
        $this->arguments[2] = function ($constraint) use ($additionalConstraints) {
            $constraint->aspectRatio();
            if(is_callable($additionalConstraints))
                $additionalConstraints($constraint);
        };

        return parent::execute($image);
    }
}


code:
<?php

namespace Intervention\Image\Imagick\Commands;

use Intervention\Image\Commands\AbstractCommand;

class InsertCommand extends AbstractCommand
{
    /**
     * Insert another image into given image
     *
     * @param  \Intervention\Image\Image $image
     * @return boolean
     */
    public function execute($image)
    {
        $source = $this->argument(0)->required()->value();
        $position = $this->argument(1)->type('string')->value();
        $x = $this->argument(2)->type('digit')->value(0);
        $y = $this->argument(3)->type('digit')->value(0);

        // build watermark
        $watermark = $image->getDriver()->init($source);

        // define insertion point
        $image_size = $image->getSize()->align($position, $x, $y);
        $watermark_size = $watermark->getSize()->align($position);
        $target = $image_size->relativePosition($watermark_size);

        // insert image at position
        return $image->getCore()->compositeImage($watermark->getCore(), \Imagick::COMPOSITE_DEFAULT, $target->x, $target->y);
    }
}


code:
<?php

namespace Intervention\Image\Imagick\Commands;

use Intervention\Image\Commands\AbstractCommand;

class InterlaceCommand extends AbstractCommand
{
    /**
     * Toggles interlaced encoding mode
     *
     * @param  \Intervention\Image\Image $image
     * @return boolean
     */
    public function execute($image)
    {
        $mode = $this->argument(0)->type('bool')->value(true);

        if ($mode) {
            $mode = \Imagick::INTERLACE_LINE;
        } else {
            $mode = \Imagick::INTERLACE_NO;
        }

        $image->getCore()->setInterlaceScheme($mode);

        return true;
    }
}


code:
<?php

namespace Intervention\Image\Imagick\Commands;

use Intervention\Image\Commands\AbstractCommand;

class InvertCommand extends AbstractCommand
{
    /**
     * Inverts colors of an image
     *
     * @param  \Intervention\Image\Image $image
     * @return boolean
     */
    public function execute($image)
    {
        return $image->getCore()->negateImage(false);
    }
}


code:
<?php

namespace Intervention\Image\Imagick\Commands;

use Intervention\Image\Commands\AbstractCommand;

class LimitColorsCommand extends AbstractCommand
{
    /**
     * Reduces colors of a given image
     *
     * @param  \Intervention\Image\Image $image
     * @return boolean
     */
    public function execute($image)
    {
        $count = $this->argument(0)->value();
        $matte = $this->argument(1)->value();

        // get current image size
        $size = $image->getSize();

        // build 2 color alpha mask from original alpha
        $alpha = clone $image->getCore();
        $alpha->separateImageChannel(\Imagick::CHANNEL_ALPHA);
        $alpha->transparentPaintImage('#ffffff', 0, 0, false);
        $alpha->separateImageChannel(\Imagick::CHANNEL_ALPHA);
        $alpha->negateImage(false);

        if ($matte) {

            // get matte color
            $mattecolor = $image->getDriver()->parseColor($matte)->getPixel();

            // create matte image
            $canvas = new \Imagick;
            $canvas->newImage($size->width, $size->height, $mattecolor, 'png');

            // lower colors of original and copy to matte
            $image->getCore()->quantizeImage($count, \Imagick::COLORSPACE_RGB, 0, false, false);
            $canvas->compositeImage($image->getCore(), \Imagick::COMPOSITE_DEFAULT, 0, 0);

            // copy new alpha to canvas
            $canvas->compositeImage($alpha, \Imagick::COMPOSITE_COPYOPACITY, 0, 0);

            // replace core
            $image->setCore($canvas);

        } else {

            $image->getCore()->quantizeImage($count, \Imagick::COLORSPACE_RGB, 0, false, false);
            $image->getCore()->compositeImage($alpha, \Imagick::COMPOSITE_COPYOPACITY, 0, 0);

        }

        return true;

    }
}


code:
<?php

namespace Intervention\Image\Imagick\Commands;

use Intervention\Image\Commands\AbstractCommand;

class MaskCommand extends AbstractCommand
{
    /**
     * Applies an alpha mask to an image
     *
     * @param  \Intervention\Image\Image $image
     * @return boolean
     */
    public function execute($image)
    {
        $mask_source = $this->argument(0)->value();
        $mask_w_alpha = $this->argument(1)->type('bool')->value(false);

        // get imagick
        $imagick = $image->getCore();

        // build mask image from source
        $mask = $image->getDriver()->init($mask_source);

        // resize mask to size of current image (if necessary)
        $image_size = $image->getSize();
        if ($mask->getSize() != $image_size) {
            $mask->resize($image_size->width, $image_size->height);
        }

        $imagick->setImageMatte(true);

        if ($mask_w_alpha) {

            // just mask with alpha map
            $imagick->compositeImage($mask->getCore(), \Imagick::COMPOSITE_DSTIN, 0, 0);

        } else {

            // get alpha channel of original as greyscale image
            $original_alpha = clone $imagick;
            $original_alpha->separateImageChannel(\Imagick::CHANNEL_ALPHA);

            // use red channel from mask ask alpha
            $mask_alpha = clone $mask->getCore();
            $mask_alpha->compositeImage($mask->getCore(), \Imagick::COMPOSITE_DEFAULT, 0, 0);
            // $mask_alpha->setImageAlphaChannel(\Imagick::ALPHACHANNEL_DEACTIVATE);
            $mask_alpha->separateImageChannel(\Imagick::CHANNEL_ALL);

            // combine both alphas from original and mask
            $original_alpha->compositeImage($mask_alpha, \Imagick::COMPOSITE_COPYOPACITY, 0, 0);

            // mask the image with the alpha combination
            $imagick->compositeImage($original_alpha, \Imagick::COMPOSITE_DSTIN, 0, 0);
        }

        return true;
    }
}


code:
<?php

namespace Intervention\Image\Imagick\Commands;

use Intervention\Image\Commands\AbstractCommand;

class OpacityCommand extends AbstractCommand
{
    /**
     * Defines opacity of an image
     *
     * @param  \Intervention\Image\Image $image
     * @return boolean
     */
    public function execute($image)
    {
        $transparency = $this->argument(0)->between(0, 100)->required()->value();

        $transparency = $transparency > 0 ? (100 / $transparency) : 1000;

        return $image->getCore()->evaluateImage(\Imagick::EVALUATE_DIVIDE, $transparency, \Imagick::CHANNEL_ALPHA);
    }
}


code:
<?php

namespace Intervention\Image\Imagick\Commands;

use Intervention\Image\Commands\AbstractCommand;
use Intervention\Image\Imagick\Color;

class PickColorCommand extends AbstractCommand
{
    /**
     * Read color information from a certain position
     *
     * @param  \Intervention\Image\Image $image
     * @return boolean
     */
    public function execute($image)
    {
        $x = $this->argument(0)->type('digit')->required()->value();
        $y = $this->argument(1)->type('digit')->required()->value();
        $format = $this->argument(2)->type('string')->value('array');

        // pick color
        $color = new Color($image->getCore()->getImagePixelColor($x, $y));

        // format to output
        $this->setOutput($color->format($format));

        return true;
    }
}


code:
<?php

namespace Intervention\Image\Imagick\Commands;

use Intervention\Image\Commands\AbstractCommand;
use Intervention\Image\Imagick\Color;

class PixelCommand extends AbstractCommand
{
    /**
     * Draws one pixel to a given image
     *
     * @param  \Intervention\Image\Image $image
     * @return boolean
     */
    public function execute($image)
    {
        $color = $this->argument(0)->required()->value();
        $color = new Color($color);
        $x = $this->argument(1)->type('digit')->required()->value();
        $y = $this->argument(2)->type('digit')->required()->value();

        // prepare pixel
        $draw = new \ImagickDraw;
        $draw->setFillColor($color->getPixel());
        $draw->point($x, $y);

        // apply pixel
        return $image->getCore()->drawImage($draw);
    }
}


code:
<?php

namespace Intervention\Image\Imagick\Commands;

use Intervention\Image\Commands\AbstractCommand;

class PixelateCommand extends AbstractCommand
{
    /**
     * Applies a pixelation effect to a given image
     *
     * @param  \Intervention\Image\Image $image
     * @return boolean
     */
    public function execute($image)
    {
        $size = $this->argument(0)->type('digit')->value(10);

        $width = $image->getWidth();
        $height = $image->getHeight();

        $image->getCore()->scaleImage(max(1, ($width / $size)), max(1, ($height / $size)));
        $image->getCore()->scaleImage($width, $height);

        return true;
    }
}


code:
<?php

namespace Intervention\Image\Imagick\Commands;

use Intervention\Image\Commands\AbstractCommand;
use Intervention\Image\Exception\RuntimeException;

class ResetCommand extends AbstractCommand
{
    /**
     * Resets given image to its backup state
     *
     * @param  \Intervention\Image\Image $image
     * @return boolean
     */
    public function execute($image)
    {
        $backupName = $this->argument(0)->value();

        $backup = $image->getBackup($backupName);

        if ($backup instanceof \Imagick) {

            // destroy current core
            $image->getCore()->clear();

            // clone backup
            $backup = clone $backup;

            // reset to new resource
            $image->setCore($backup);

            return true;
        }

        throw new RuntimeException(
            "Backup not available. Call backup({$backupName}) before reset()."
        );
    }
}


code:
<?php

namespace Intervention\Image\Imagick\Commands;

use Intervention\Image\Commands\AbstractCommand;

class ResizeCanvasCommand extends AbstractCommand
{
    /**
     * Resizes image boundaries
     *
     * @param  \Intervention\Image\Image $image
     * @return boolean
     */
    public function execute($image)
    {
        $width = $this->argument(0)->type('digit')->required()->value();
        $height = $this->argument(1)->type('digit')->required()->value();
        $anchor = $this->argument(2)->value('center');
        $relative = $this->argument(3)->type('boolean')->value(false);
        $bgcolor = $this->argument(4)->value();

        $original_width = $image->getWidth();
        $original_height = $image->getHeight();

        // check of only width or height is set
        $width = is_null($width) ? $original_width : intval($width);
        $height = is_null($height) ? $original_height : intval($height);

        // check on relative width/height
        if ($relative) {
            $width = $original_width + $width;
            $height = $original_height + $height;
        }

        // check for negative width/height
        $width = ($width <= 0) ? $width + $original_width : $width;
        $height = ($height <= 0) ? $height + $original_height : $height;

        // create new canvas
        $canvas = $image->getDriver()->newImage($width, $height, $bgcolor);

        // set copy position
        $canvas_size = $canvas->getSize()->align($anchor);
        $image_size = $image->getSize()->align($anchor);
        $canvas_pos = $image_size->relativePosition($canvas_size);
        $image_pos = $canvas_size->relativePosition($image_size);

        if ($width <= $original_width) {
            $dst_x = 0;
            $src_x = $canvas_pos->x;
            $src_w = $canvas_size->width;
        } else {
            $dst_x = $image_pos->x;
            $src_x = 0;
            $src_w = $original_width;
        }

        if ($height <= $original_height) {
            $dst_y = 0;
            $src_y = $canvas_pos->y;
            $src_h = $canvas_size->height;
        } else {
            $dst_y = $image_pos->y;
            $src_y = 0;
            $src_h = $original_height;
        }

        // make image area transparent to keep transparency
        // even if background-color is set
        $rect = new \ImagickDraw;
        $fill = $canvas->pickColor(0, 0, 'hex');
        $fill = $fill == '#ff0000' ? '#00ff00' : '#ff0000';
        $rect->setFillColor($fill);
        $rect->rectangle($dst_x, $dst_y, $dst_x + $src_w - 1, $dst_y + $src_h - 1);
        $canvas->getCore()->drawImage($rect);
        $canvas->getCore()->transparentPaintImage($fill, 0, 0, false);

        $canvas->getCore()->setImageColorspace($image->getCore()->getImageColorspace());

        // copy image into new canvas
        $image->getCore()->cropImage($src_w, $src_h, $src_x, $src_y);
        $canvas->getCore()->compositeImage($image->getCore(), \Imagick::COMPOSITE_DEFAULT, $dst_x, $dst_y);
        $canvas->getCore()->setImagePage(0,0,0,0);

        // set new core to canvas
        $image->setCore($canvas->getCore());

        return true;
    }
}


code:
<?php

namespace Intervention\Image\Imagick\Commands;

use Intervention\Image\Commands\AbstractCommand;

class ResizeCommand extends AbstractCommand
{
    /**
     * Resizes image dimensions
     *
     * @param  \Intervention\Image\Image $image
     * @return boolean
     */
    public function execute($image)
    {
        $width = $this->argument(0)->value();
        $height = $this->argument(1)->value();
        $constraints = $this->argument(2)->type('closure')->value();

        // resize box
        $resized = $image->getSize()->resize($width, $height, $constraints);

        // modify image
        $image->getCore()->scaleImage($resized->getWidth(), $resized->getHeight());

        return true;
    }
}


code:
<?php

namespace Intervention\Image\Imagick\Commands;

use Intervention\Image\Commands\AbstractCommand;
use Intervention\Image\Imagick\Color;

class RotateCommand extends AbstractCommand
{
    /**
     * Rotates image counter clockwise
     *
     * @param  \Intervention\Image\Image $image
     * @return boolean
     */
    public function execute($image)
    {
        $angle = $this->argument(0)->type('numeric')->required()->value();
        $color = $this->argument(1)->value();
        $color = new Color($color);

        // restrict rotations beyond 360 degrees, since the end result is the same
        $angle %= 360;

        // rotate image
        $image->getCore()->rotateImage($color->getPixel(), ($angle * -1));

        return true;
    }
}


code:
<?php

namespace Intervention\Image\Imagick\Commands;

use Intervention\Image\Commands\AbstractCommand;

class SharpenCommand extends AbstractCommand
{
    /**
     * Sharpen image
     *
     * @param  \Intervention\Image\Image $image
     * @return boolean
     */
    public function execute($image)
    {
        $amount = $this->argument(0)->between(0, 100)->value(10);

        return $image->getCore()->unsharpMaskImage(1, 1, $amount / 6.25, 0);
    }
}


code:
<?php

namespace Intervention\Image\Imagick\Commands;

use Intervention\Image\Commands\AbstractCommand;
use Intervention\Image\Imagick\Color;

class TrimCommand extends AbstractCommand
{
    /**
     * Trims away parts of an image
     *
     * @param  \Intervention\Image\Image $image
     * @return boolean
     */
    public function execute($image)
    {
        $base = $this->argument(0)->type('string')->value();
        $away = $this->argument(1)->value();
        $tolerance = $this->argument(2)->type('numeric')->value(0);
        $feather = $this->argument(3)->type('numeric')->value(0);

        $width = $image->getWidth();
        $height = $image->getHeight();

        $checkTransparency = false;

        // define borders to trim away
        if (is_null($away)) {
            $away = ['top', 'right', 'bottom', 'left'];
        } elseif (is_string($away)) {
            $away = [$away];
        }

        // lower border names
        foreach ($away as $key => $value) {
            $away[$key] = strtolower($value);
        }

        // define base color position
        switch (strtolower($base)) {
            case 'transparent':
            case 'trans':
                $checkTransparency = true;
                $base_x = 0;
                $base_y = 0;
                break;

            case 'bottom-right':
            case 'right-bottom':
                $base_x = $width - 1;
                $base_y = $height - 1;
                break;

            default:
            case 'top-left':
            case 'left-top':
                $base_x = 0;
                $base_y = 0;
                break;
        }

        // pick base color
        if ($checkTransparency) {
            $base_color = new Color; // color will only be used to compare alpha channel
        } else {
            $base_color = $image->pickColor($base_x, $base_y, 'object');
        }

        // trim on clone to get only coordinates
        $trimed = clone $image->getCore();

        // add border to trim specific color
        $trimed->borderImage($base_color->getPixel(), 1, 1);

        // trim image
        $trimed->trimImage(65850 / 100 * $tolerance);

        // get coordinates of trim
        $imagePage = $trimed->getImagePage();
        list($crop_x, $crop_y) = [$imagePage['x']-1, $imagePage['y']-1];
        // $trimed->setImagePage(0, 0, 0, 0);
        list($crop_width, $crop_height) = [$trimed->width, $trimed->height];

        // adjust settings if right should not be trimed
        if ( ! in_array('right', $away)) {
            $crop_width = $crop_width + ($width - ($width - $crop_x));
        }

        // adjust settings if bottom should not be trimed
        if ( ! in_array('bottom', $away)) {
            $crop_height = $crop_height + ($height - ($height - $crop_y));
        }

        // adjust settings if left should not be trimed
        if ( ! in_array('left', $away)) {
            $crop_width = $crop_width + $crop_x;
            $crop_x = 0;
        }

        // adjust settings if top should not be trimed
        if ( ! in_array('top', $away)) {
            $crop_height = $crop_height + $crop_y;
            $crop_y = 0;
        }

        // add feather
        $crop_width = min($width, ($crop_width + $feather * 2));
        $crop_height = min($height, ($crop_height + $feather * 2));
        $crop_x = max(0, ($crop_x - $feather));
        $crop_y = max(0, ($crop_y - $feather));

        // finally crop based on page
        $image->getCore()->cropImage($crop_width, $crop_height, $crop_x, $crop_y);
        $image->getCore()->setImagePage(0,0,0,0);

        $trimed->destroy();

        return true;
    }
}