code:
<?php

namespace Intervention\Image;

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

abstract class AbstractColor
{
    /**
     * Initiates color object from integer
     *
     * @param  int $value
     * @return \Intervention\Image\AbstractColor
     */
    abstract public function initFromInteger($value);

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

    /**
     * Initiates color object from given string
     *
     * @param  string $value
     * @return \Intervention\Image\AbstractColor
     */
    abstract public function initFromString($value);

    /**
     * Initiates color object from given ImagickPixel object
     *
     * @param  ImagickPixel $value
     * @return \Intervention\Image\AbstractColor
     */
    abstract public function initFromObject($value);

    /**
     * Initiates color object from given R, G and B values
     *
     * @param  int $r
     * @param  int $g
     * @param  int $b
     * @return \Intervention\Image\AbstractColor
     */
    abstract public function initFromRgb($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
     */
    abstract public function initFromRgba($r, $g, $b, $a);

    /**
     * Calculates integer value of current color instance
     *
     * @return int
     */
    abstract public function getInt();

    /**
     * Calculates hexadecimal value of current color instance
     *
     * @param  string $prefix
     * @return string
     */
    abstract public function getHex($prefix);

    /**
     * Calculates RGB(A) in array format of current color instance
     *
     * @return array
     */
    abstract public function getArray();

    /**
     * Calculates RGBA in string format of current color instance
     *
     * @return string
     */
    abstract public function getRgba();

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

    /**
     * Creates new instance
     *
     * @param mixed $value
     */
    public function __construct($value = null)
    {
        $this->parse($value);
    }

    /**
     * Parses given value as color
     *
     * @param  mixed $value
     * @return \Intervention\Image\AbstractColor
     */
    public function parse($value)
    {
        switch (true) {

            case is_string($value):
                $this->initFromString($value);
                break;

            case is_int($value):
                $this->initFromInteger($value);
                break;

            case is_array($value):
                $this->initFromArray($value);
                break;

            case is_object($value):
                $this->initFromObject($value);
                break;

            case is_null($value):
                $this->initFromArray([255, 255, 255, 0]);
                break;

            default:
                throw new NotReadableException(
                    "Color format ({$value}) cannot be read."
                );
        }

        return $this;
    }

    /**
     * Formats current color instance into given format
     *
     * @param  string $type
     * @return mixed
     */
    public function format($type)
    {
        switch (strtolower($type)) {

            case 'rgba':
                return $this->getRgba();

            case 'hex':
                return $this->getHex('#');

            case 'int':
            case 'integer':
                return $this->getInt();

            case 'array':
                return $this->getArray();

            case 'obj':
            case 'object':
                return $this;

            default:
                throw new NotSupportedException(
                    "Color format ({$type}) is not supported."
                );
        }
    }

    /**
     * Reads RGBA values from string into array
     *
     * @param  string $value
     * @return array
     */
    protected function rgbaFromString($value)
    {
        $result = false;

        // parse color string in hexidecimal format like #cccccc or cccccc or ccc
        $hexPattern = '/^#?([a-f0-9]{1,2})([a-f0-9]{1,2})([a-f0-9]{1,2})$/i';

        // parse color string in format rgb(140, 140, 140)
        $rgbPattern = '/^rgb ?\(([0-9]{1,3}), ?([0-9]{1,3}), ?([0-9]{1,3})\)$/i';

        // parse color string in format rgba(255, 0, 0, 0.5)
        $rgbaPattern = '/^rgba ?\(([0-9]{1,3}), ?([0-9]{1,3}), ?([0-9]{1,3}), ?([0-9.]{1,4})\)$/i';

        if (preg_match($hexPattern, $value, $matches)) {
            $result = [];
            $result[0] = strlen($matches[1]) == '1' ? hexdec($matches[1].$matches[1]) : hexdec($matches[1]);
            $result[1] = strlen($matches[2]) == '1' ? hexdec($matches[2].$matches[2]) : hexdec($matches[2]);
            $result[2] = strlen($matches[3]) == '1' ? hexdec($matches[3].$matches[3]) : hexdec($matches[3]);
            $result[3] = 1;
        } elseif (preg_match($rgbPattern, $value, $matches)) {
            $result = [];
            $result[0] = ($matches[1] >= 0 && $matches[1] <= 255) ? intval($matches[1]) : 0;
            $result[1] = ($matches[2] >= 0 && $matches[2] <= 255) ? intval($matches[2]) : 0;
            $result[2] = ($matches[3] >= 0 && $matches[3] <= 255) ? intval($matches[3]) : 0;
            $result[3] = 1;
        } elseif (preg_match($rgbaPattern, $value, $matches)) {
            $result = [];
            $result[0] = ($matches[1] >= 0 && $matches[1] <= 255) ? intval($matches[1]) : 0;
            $result[1] = ($matches[2] >= 0 && $matches[2] <= 255) ? intval($matches[2]) : 0;
            $result[2] = ($matches[3] >= 0 && $matches[3] <= 255) ? intval($matches[3]) : 0;
            $result[3] = ($matches[4] >= 0 && $matches[4] <= 1) ? $matches[4] : 0;
        } else {
            throw new NotReadableException(
                "Unable to read color ({$value})."
            );
        }

        return $result;
    }
}


code:
<?php

namespace Intervention\Image;

use GuzzleHttp\Psr7\Stream;
use Intervention\Image\Exception\NotReadableException;
use Psr\Http\Message\StreamInterface;

abstract class AbstractDecoder
{
    /**
     * Initiates new image from path in filesystem
     *
     * @param  string $path
     * @return \Intervention\Image\Image
     */
    abstract public function initFromPath($path);

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

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

    /**
     * Initiates new image from Imagick object
     *
     * @param \Imagick $object
     * @return \Intervention\Image\Image
     */
    abstract public function initFromImagick(\Imagick $object);

    /**
     * Buffer of input data
     *
     * @var mixed
     */
    private $data;

    /**
     * Creates new Decoder with data
     *
     * @param mixed $data
     */
    public function __construct($data = null)
    {
        $this->data = $data;
    }

    /**
     * Init from given URL
     *
     * @param  string $url
     * @return \Intervention\Image\Image
     */
    public function initFromUrl($url)
    {

        $options = [
            'http' => [
                'method'=>"GET",
                'header'=>"Accept-language: en\r\n".
                "User-Agent: Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.2 (KHTML, like Gecko) Chrome/22.0.1216.0 Safari/537.2\r\n"
          ]
        ];

        $context  = stream_context_create($options);

        if ($data = @file_get_contents($url, false, $context)) {
            return $this->initFromBinary($data);
        }

        throw new NotReadableException(
            "Unable to init from given url (".$url.")."
        );
    }

    /**
     * Init from given stream
     *
     * @param StreamInterface|resource $stream
     * @return \Intervention\Image\Image
     */
    public function initFromStream($stream)
    {
        if (!$stream instanceof StreamInterface) {
            $stream = new Stream($stream);
        }

        try {
            $offset = $stream->tell();
        } catch (\RuntimeException $e) {
            $offset = 0;
        }

        $shouldAndCanSeek = $offset !== 0 && $stream->isSeekable();

        if ($shouldAndCanSeek) {
            $stream->rewind();
        }

        try {
            $data = $stream->getContents();
        } catch (\RuntimeException $e) {
            $data = null;
        }

        if ($shouldAndCanSeek) {
            $stream->seek($offset);
        }

        if ($data) {
            return $this->initFromBinary($data);
        }

        throw new NotReadableException(
            "Unable to init from given stream"
        );
    }

    /**
     * Determines if current source data is GD resource
     *
     * @return boolean
     */
    public function isGdResource()
    {
        if (is_resource($this->data)) {
            return (get_resource_type($this->data) == 'gd');
        }

        return false;
    }

    /**
     * Determines if current source data is Imagick object
     *
     * @return boolean
     */
    public function isImagick()
    {
        return is_a($this->data, 'Imagick');
    }

    /**
     * Determines if current source data is Intervention\Image\Image object
     *
     * @return boolean
     */
    public function isInterventionImage()
    {
        return is_a($this->data, '\Intervention\Image\Image');
    }

    /**
     * Determines if current data is SplFileInfo object
     *
     * @return boolean
     */
    public function isSplFileInfo()
    {
        return is_a($this->data, 'SplFileInfo');
    }

    /**
     * Determines if current data is Symfony UploadedFile component
     *
     * @return boolean
     */
    public function isSymfonyUpload()
    {
        return is_a($this->data, 'Symfony\Component\HttpFoundation\File\UploadedFile');
    }

    /**
     * Determines if current source data is file path
     *
     * @return boolean
     */
    public function isFilePath()
    {
        if (is_string($this->data)) {
            try {
                return is_file($this->data);
            } catch (\Exception $e) {
                return false;
            }
        }

        return false;
    }

    /**
     * Determines if current source data is url
     *
     * @return boolean
     */
    public function isUrl()
    {
        return (bool) filter_var($this->data, FILTER_VALIDATE_URL);
    }

    /**
     * Determines if current source data is a stream resource
     *
     * @return boolean
     */
    public function isStream()
    {
        if ($this->data instanceof StreamInterface) return true;
        if (!is_resource($this->data)) return false;
        if (get_resource_type($this->data) !== 'stream') return false;

        return true;
    }

    /**
     * Determines if current source data is binary data
     *
     * @return boolean
     */
    public function isBinary()
    {
        if (is_string($this->data)) {
            $mime = finfo_buffer(finfo_open(FILEINFO_MIME_TYPE), $this->data);
            return (substr($mime, 0, 4) != 'text' && $mime != 'application/x-empty');
        }

        return false;
    }

    /**
     * Determines if current source data is data-url
     *
     * @return boolean
     */
    public function isDataUrl()
    {
        $data = $this->decodeDataUrl($this->data);

        return is_null($data) ? false : true;
    }

    /**
     * Determines if current source data is base64 encoded
     *
     * @return boolean
     */
    public function isBase64()
    {
        if (!is_string($this->data)) {
            return false;
        }

        return base64_encode(base64_decode($this->data)) === str_replace(["\n", "\r"], '', $this->data);
    }

    /**
     * Initiates new Image from Intervention\Image\Image
     *
     * @param  Image $object
     * @return \Intervention\Image\Image
     */
    public function initFromInterventionImage($object)
    {
        return $object;
    }

    /**
     * Parses and decodes binary image data from data-url
     *
     * @param  string $data_url
     * @return string
     */
    private function decodeDataUrl($data_url)
    {
        if (!is_string($data_url)) {
            return null;
        }

        $pattern = "/^data:(?:image\/[a-zA-Z\-\.]+)(?:charset=\".+\")?;base64,(?P<data>.+)$/";
        preg_match($pattern, $data_url, $matches);

        if (is_array($matches) && array_key_exists('data', $matches)) {
            return base64_decode($matches['data']);
        }

        return null;
    }

    /**
     * Initiates new image from mixed data
     *
     * @param  mixed $data
     * @return \Intervention\Image\Image
     */
    public function init($data)
    {
        $this->data = $data;

        switch (true) {

            case $this->isGdResource():
                return $this->initFromGdResource($this->data);

            case $this->isImagick():
                return $this->initFromImagick($this->data);

            case $this->isInterventionImage():
                return $this->initFromInterventionImage($this->data);

            case $this->isSplFileInfo():
                return $this->initFromPath($this->data->getRealPath());

            case $this->isBinary():
                return $this->initFromBinary($this->data);

            case $this->isUrl():
                return $this->initFromUrl($this->data);

            case $this->isStream():
                return $this->initFromStream($this->data);

            case $this->isDataUrl():
                return $this->initFromBinary($this->decodeDataUrl($this->data));

            case $this->isFilePath():
                return $this->initFromPath($this->data);

            // isBase64 has to be after isFilePath to prevent false positives
            case $this->isBase64():
                return $this->initFromBinary(base64_decode($this->data));

            default:
                throw new NotReadableException("Image source not readable");
        }
    }

    /**
     * Decoder object transforms to string source data
     *
     * @return string
     */
    public function __toString()
    {
        return (string) $this->data;
    }
}

license: mit


code:
<?php

namespace Intervention\Image;

use Intervention\Image\Exception\NotSupportedException;

abstract class AbstractDriver
{
    /**
     * Decoder instance to init images from
     *
     * @var \Intervention\Image\AbstractDecoder
     */
    public $decoder;

    /**
     * Image encoder instance
     *
     * @var \Intervention\Image\AbstractEncoder
     */
    public $encoder;

    /**
     * Creates new image instance
     *
     * @param  int     $width
     * @param  int     $height
     * @param  string  $background
     * @return \Intervention\Image\Image
     */
    abstract public function newImage($width, $height, $background);

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

    /**
     * Checks if core module installation is available
     *
     * @return boolean
     */
    abstract protected function coreAvailable();

    /**
     * Returns clone of given core
     *
     * @return mixed
     */
    public function cloneCore($core)
    {
        return clone $core;
    }

    /**
     * Initiates new image from given input
     *
     * @param  mixed $data
     * @return \Intervention\Image\Image
     */
    public function init($data)
    {
        return $this->decoder->init($data);
    }

    /**
     * Encodes given image
     *
     * @param  Image   $image
     * @param  string  $format
     * @param  int     $quality
     * @return \Intervention\Image\Image
     */
    public function encode($image, $format, $quality)
    {
        return $this->encoder->process($image, $format, $quality);
    }

    /**
     * Executes named command on given image
     *
     * @param  Image  $image
     * @param  string $name
     * @param  array $arguments
     * @return \Intervention\Image\Commands\AbstractCommand
     */
    public function executeCommand($image, $name, $arguments)
    {
        $commandName = $this->getCommandClassName($name);
        $command = new $commandName($arguments);
        $command->execute($image);

        return $command;
    }

    /**
     * Returns classname of given command name
     *
     * @param  string $name
     * @return string
     */
    private function getCommandClassName($name)
    {
        $name = mb_convert_case($name[0], MB_CASE_UPPER, 'utf-8') . mb_substr($name, 1, mb_strlen($name));

        $drivername = $this->getDriverName();
        $classnameLocal = sprintf('\Intervention\Image\%s\Commands\%sCommand', $drivername, ucfirst($name));
        $classnameGlobal = sprintf('\Intervention\Image\Commands\%sCommand', ucfirst($name));

        if (class_exists($classnameLocal)) {
            return $classnameLocal;
        } elseif (class_exists($classnameGlobal)) {
            return $classnameGlobal;
        }

        throw new NotSupportedException(
            "Command ({$name}) is not available for driver ({$drivername})."
        );
    }

    /**
     * Returns name of current driver instance
     *
     * @return string
     */
    public function getDriverName()
    {
        $reflect = new \ReflectionClass($this);
        $namespace = $reflect->getNamespaceName();

        return substr(strrchr($namespace, "\\"), 1);
    }
}


code:
<?php

namespace Intervention\Image;

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

abstract class AbstractEncoder
{
    /**
     * Buffer of encode result data
     *
     * @var string
     */
    public $result;

    /**
     * Image object to encode
     *
     * @var Image
     */
    public $image;

    /**
     * Output format of encoder instance
     *
     * @var string
     */
    public $format;

    /**
     * Output quality of encoder instance
     *
     * @var int
     */
    public $quality;

    /**
     * Processes and returns encoded image as JPEG string
     *
     * @return string
     */
    abstract protected function processJpeg();

    /**
     * Processes and returns encoded image as PNG string
     *
     * @return string
     */
    abstract protected function processPng();

    /**
     * Processes and returns encoded image as GIF string
     *
     * @return string
     */
    abstract protected function processGif();

    /**
     * Processes and returns encoded image as TIFF string
     *
     * @return string
     */
    abstract protected function processTiff();

    /**
     * Processes and returns encoded image as BMP string
     *
     * @return string
     */
    abstract protected function processBmp();

    /**
     * Processes and returns encoded image as ICO string
     *
     * @return string
     */
    abstract protected function processIco();

    /**
     * Processes and returns image as WebP encoded string
     *
     * @return string
     */
    abstract protected function processWebp();

    /**
     * Process a given image
     *
     * @param  Image   $image
     * @param  string  $format
     * @param  int     $quality
     * @return Image
     */
    public function process(Image $image, $format = null, $quality = null)
    {
        $this->setImage($image);
        $this->setFormat($format);
        $this->setQuality($quality);

        switch (strtolower($this->format)) {

            case 'data-url':
                $this->result = $this->processDataUrl();
                break;

            case 'gif':
            case 'image/gif':
                $this->result = $this->processGif();
                break;

            case 'png':
            case 'image/png':
            case 'image/x-png':
                $this->result = $this->processPng();
                break;

            case 'jpg':
            case 'jpeg':
            case 'image/jpg':
            case 'image/jpeg':
            case 'image/pjpeg':
                $this->result = $this->processJpeg();
                break;

            case 'tif':
            case 'tiff':
            case 'image/tiff':
            case 'image/tif':
            case 'image/x-tif':
            case 'image/x-tiff':
                $this->result = $this->processTiff();
                break;

            case 'bmp':
            case 'bmp':
            case 'ms-bmp':
            case 'x-bitmap':
            case 'x-bmp':
            case 'x-ms-bmp':
            case 'x-win-bitmap':
            case 'x-windows-bmp':
            case 'x-xbitmap':
            case 'image/ms-bmp':
            case 'image/x-bitmap':
            case 'image/x-bmp':
            case 'image/x-ms-bmp':
            case 'image/x-win-bitmap':
            case 'image/x-windows-bmp':
            case 'image/x-xbitmap':
                $this->result = $this->processBmp();
                break;

            case 'ico':
            case 'image/x-ico':
            case 'image/x-icon':
            case 'image/vnd.microsoft.icon':
                $this->result = $this->processIco();
                break;

            case 'psd':
            case 'image/vnd.adobe.photoshop':
                $this->result = $this->processPsd();
                break;

            case 'webp':
            case 'image/webp':
            case 'image/x-webp':
                $this->result = $this->processWebp();
                break;

            default:
                throw new NotSupportedException(
                    "Encoding format ({$format}) is not supported."
                );
        }

        $this->setImage(null);

        return $image->setEncoded($this->result);
    }

    /**
     * Processes and returns encoded image as data-url string
     *
     * @return string
     */
    protected function processDataUrl()
    {
        $mime = $this->image->mime ? $this->image->mime : 'image/png';

        return sprintf('data:%s;base64,%s',
            $mime,
            base64_encode($this->process($this->image, $mime, $this->quality))
        );
    }

    /**
     * Sets image to process
     *
     * @param Image $image
     */
    protected function setImage($image)
    {
        $this->image = $image;
    }

    /**
     * Determines output format
     *
     * @param string $format
     */
    protected function setFormat($format = null)
    {
        if ($format == '' && $this->image instanceof Image) {
            $format = $this->image->mime;
        }

        $this->format = $format ? $format : 'jpg';

        return $this;
    }

    /**
     * Determines output quality
     *
     * @param int $quality
     */
    protected function setQuality($quality)
    {
        $quality = is_null($quality) ? 90 : $quality;
        $quality = $quality === 0 ? 1 : $quality;

        if ($quality < 0 || $quality > 100) {
            throw new InvalidArgumentException(
                'Quality must range from 0 to 100.'
            );
        }

        $this->quality = intval($quality);

        return $this;
    }
}


code:
<?php

namespace Intervention\Image;

abstract class AbstractFont
{
    /**
     * Text to be written
     *
     * @var String
     */
    public $text;

    /**
     * Text size in pixels
     *
     * @var int
     */
    public $size = 12;

    /**
     * Color of the text
     *
     * @var mixed
     */
    public $color = '000000';

    /**
     * Rotation angle of the text
     *
     * @var int
     */
    public $angle = 0;

    /**
     * Horizontal alignment of the text
     *
     * @var String
     */
    public $align;

    /**
     * Vertical alignment of the text
     *
     * @var String
     */
    public $valign;

    /**
     * Path to TTF or GD library internal font file of the text
     *
     * @var mixed
     */
    public $file;

    /**
     * Draws font to given image on given position
     *
     * @param  Image   $image
     * @param  int     $posx
     * @param  int     $posy
     * @return boolean
     */
    abstract public function applyToImage(Image $image, $posx = 0, $posy = 0);

    /**
     * Calculates bounding box of current font setting
     *
     * @return array
     */
    abstract public function getBoxSize();

    /**
     * Create a new instance of Font
     *
     * @param Strinf $text Text to be written
     */
    public function __construct($text = null)
    {
        $this->text = $text;
    }

    /**
     * Set text to be written
     *
     * @param  String $text
     * @return void
     */
    public function text($text)
    {
        $this->text = $text;

        return $this;
    }

    /**
     * Get text to be written
     *
     * @return String
     */
    public function getText()
    {
        return $this->text;
    }

    /**
     * Set font size in pixels
     *
     * @param  int $size
     * @return void
     */
    public function size($size)
    {
        $this->size = $size;

        return $this;
    }

    /**
     * Get font size in pixels
     *
     * @return int
     */
    public function getSize()
    {
        return $this->size;
    }

    /**
     * Set color of text to be written
     *
     * @param  mixed $color
     * @return void
     */
    public function color($color)
    {
        $this->color = $color;

        return $this;
    }

    /**
     * Get color of text
     *
     * @return mixed
     */
    public function getColor()
    {
        return $this->color;
    }

    /**
     * Set rotation angle of text
     *
     * @param  int $angle
     * @return void
     */
    public function angle($angle)
    {
        $this->angle = $angle;

        return $this;
    }

    /**
     * Get rotation angle of text
     *
     * @return int
     */
    public function getAngle()
    {
        return $this->angle;
    }

    /**
     * Set horizontal text alignment
     *
     * @param  string $align
     * @return void
     */
    public function align($align)
    {
        $this->align = $align;

        return $this;
    }

    /**
     * Get horizontal text alignment
     *
     * @return string
     */
    public function getAlign()
    {
        return $this->align;
    }

    /**
     * Set vertical text alignment
     *
     * @param  string $valign
     * @return void
     */
    public function valign($valign)
    {
        $this->valign = $valign;

        return $this;
    }

    /**
     * Get vertical text alignment
     *
     * @return string
     */
    public function getValign()
    {
        return $this->valign;
    }

    /**
     * Set path to font file
     *
     * @param  string $file
     * @return void
     */
    public function file($file)
    {
        $this->file = $file;

        return $this;
    }

    /**
     * Get path to font file
     *
     * @return string
     */
    public function getFile()
    {
        return $this->file;
    }

    /**
     * Checks if current font has access to an applicable font file
     *
     * @return boolean
     */
    protected function hasApplicableFontFile()
    {
        if (is_string($this->file)) {
            return file_exists($this->file);
        }

        return false;
    }

    /**
     * Counts lines of text to be written
     *
     * @return int
     */
    public function countLines()
    {
        return count(explode(PHP_EOL, $this->text));
    }
}


code:
<?php

namespace Intervention\Image;

abstract class AbstractShape
{
    /**
     * Background color of shape
     *
     * @var string
     */
    public $background;

    /**
     * Border color of current shape
     *
     * @var string
     */
    public $border_color;

    /**
     * Border width of shape
     *
     * @var int
     */
    public $border_width = 0;

    /**
     * Draws shape to given image on given position
     *
     * @param  Image   $image
     * @param  int     $posx
     * @param  int     $posy
     * @return boolean
     */
    abstract public function applyToImage(Image $image, $posx = 0, $posy = 0);

    /**
     * Set text to be written
     *
     * @param  string $text
     * @return void
     */
    public function background($color)
    {
        $this->background = $color;
    }

    /**
     * Set border width and color of current shape
     *
     * @param  int     $width
     * @param  string  $color
     * @return void
     */
    public function border($width, $color = null)
    {
        $this->border_width = is_numeric($width) ? intval($width) : 0;
        $this->border_color = is_null($color) ? '#000000' : $color;
    }

    /**
     * Determines if current shape has border
     *
     * @return boolean
     */
    public function hasBorder()
    {
        return ($this->border_width >= 1);
    }
}


code:
<?php

namespace Intervention\Image\Commands;

use Intervention\Image\Commands\Argument;

abstract class AbstractCommand
{
    /**
     * Arguments of command
     *
     * @var array
     */
    public $arguments;

    /**
     * Output of command
     *
     * @var mixed
     */
    protected $output;

    /**
     * Executes current command on given image
     *
     * @param  \Intervention\Image\Image $image
     * @return mixed
     */
    abstract public function execute($image);

    /**
     * Creates new command instance
     *
     * @param array $arguments
     */
    public function __construct($arguments)
    {
        $this->arguments = $arguments;
    }

    /**
     * Creates new argument instance from given argument key
     *
     * @param  int $key
     * @return \Intervention\Image\Commands\Argument
     */
    public function argument($key)
    {
        return new Argument($this, $key);
    }

    /**
     * Returns output data of current command
     *
     * @return mixed
     */
    public function getOutput()
    {
        return $this->output ? $this->output : null;
    }

    /**
     * Determines if current instance has output data
     *
     * @return boolean
     */
    public function hasOutput()
    {
        return ! is_null($this->output);
    }

    /**
     * Sets output data of current command
     *
     * @param mixed $value
     */
    public function setOutput($value)
    {
        $this->output = $value;
    }
}


code:
<?php

namespace Intervention\Image\Commands;

use Intervention\Image\Exception\InvalidArgumentException;

class Argument
{
    /**
     * Command with arguments
     *
     * @var AbstractCommand
     */
    public $command;

    /**
     * Key of argument in array
     *
     * @var int
     */
    public $key;

    /**
     * Creates new instance from given command and key
     *
     * @param AbstractCommand $command
     * @param int             $key
     */
    public function __construct(AbstractCommand $command, $key = 0)
    {
        $this->command = $command;
        $this->key = $key;
    }

    /**
     * Returns name of current arguments command
     *
     * @return string
     */
    public function getCommandName()
    {
        preg_match("/\\\\([\w]+)Command$/", get_class($this->command), $matches);
        return isset($matches[1]) ? lcfirst($matches[1]).'()' : 'Method';
    }

    /**
     * Returns value of current argument
     *
     * @param  mixed $default
     * @return mixed
     */
    public function value($default = null)
    {
        $arguments = $this->command->arguments;

        if (is_array($arguments)) {
            return isset($arguments[$this->key]) ? $arguments[$this->key] : $default;
        }

        return $default;
    }

    /**
     * Defines current argument as required
     *
     * @return \Intervention\Image\Commands\Argument
     */
    public function required()
    {
        if ( ! array_key_exists($this->key, $this->command->arguments)) {
            throw new InvalidArgumentException(
                sprintf("Missing argument %d for %s", $this->key + 1, $this->getCommandName())
            );
        }

        return $this;
    }

    /**
     * Determines that current argument must be of given type
     *
     * @return \Intervention\Image\Commands\Argument
     */
    public function type($type)
    {
        $valid = true;
        $value = $this->value();

        if ($value === null) {
            return $this;
        }

        switch (strtolower($type)) {
            case 'bool':
            case 'boolean':
                $valid = \is_bool($value);
                $message = '%s accepts only boolean values as argument %d.';
                break;
            case 'int':
            case 'integer':
                $valid = \is_int($value);
                $message = '%s accepts only integer values as argument %d.';
                break;
            case 'num':
            case 'numeric':
                $valid = is_numeric($value);
                $message = '%s accepts only numeric values as argument %d.';
                break;
            case 'str':
            case 'string':
                $valid = \is_string($value);
                $message = '%s accepts only string values as argument %d.';
                break;
            case 'array':
                $valid = \is_array($value);
                $message = '%s accepts only array as argument %d.';
                break;
            case 'closure':
                $valid = is_a($value, '\Closure');
                $message = '%s accepts only Closure as argument %d.';
                break;
            case 'digit':
                $valid = $this->isDigit($value);
                $message = '%s accepts only integer values as argument %d.';
                break;
        }

        if (! $valid) {
            $commandName = $this->getCommandName();
            $argument = $this->key + 1;

            if (isset($message)) {
                $message = sprintf($message, $commandName, $argument);
            } else {
                $message = sprintf('Missing argument for %d.', $argument);
            }

            throw new InvalidArgumentException(
                $message
            );
        }

        return $this;
    }

    /**
     * Determines that current argument value must be numeric between given values
     *
     * @return \Intervention\Image\Commands\Argument
     */
    public function between($x, $y)
    {
        $value = $this->type('numeric')->value();

        if (is_null($value)) {
            return $this;
        }

        $alpha = min($x, $y);
        $omega = max($x, $y);

        if ($value < $alpha || $value > $omega) {
            throw new InvalidArgumentException(
                sprintf('Argument %d must be between %s and %s.', $this->key, $x, $y)
            );
        }

        return $this;
    }

    /**
     * Determines that current argument must be over a minimum value
     *
     * @return \Intervention\Image\Commands\Argument
     */
    public function min($value)
    {
        $v = $this->type('numeric')->value();

        if (is_null($v)) {
            return $this;
        }

        if ($v < $value) {
            throw new InvalidArgumentException(
                sprintf('Argument %d must be at least %s.', $this->key, $value)
            );
        }

        return $this;
    }

    /**
     * Determines that current argument must be under a maxiumum value
     *
     * @return \Intervention\Image\Commands\Argument
     */
    public function max($value)
    {
        $v = $this->type('numeric')->value();

        if (is_null($v)) {
            return $this;
        }

        if ($v > $value) {
            throw new InvalidArgumentException(
                sprintf('Argument %d may not be greater than %s.', $this->key, $value)
            );
        }

        return $this;
    }

    /**
     * Checks if value is "PHP" integer (120 but also 120.0)
     *
     * @param  mixed $value
     * @return boolean
     */
    private function isDigit($value)
    {
        return is_numeric($value) ? intval($value) == $value : false;
    }
}


code:
<?php

namespace Intervention\Image\Commands;

class ChecksumCommand extends AbstractCommand
{
    /**
     * Calculates checksum of given image
     *
     * @param  \Intervention\Image\Image $image
     * @return boolean
     */
    public function execute($image)
    {
        $colors = [];

        $size = $image->getSize();

        for ($x=0; $x <= ($size->width-1); $x++) {
            for ($y=0; $y <= ($size->height-1); $y++) {
                $colors[] = $image->pickColor($x, $y, 'array');
            }
        }

        $this->setOutput(md5(serialize($colors)));

        return true;
    }
}


code:
<?php

namespace Intervention\Image\Commands;

use Closure;

class CircleCommand extends AbstractCommand
{
    /**
     * Draw a circle centered on given image
     *
     * @param  \Intervention\Image\image $image
     * @return boolean
     */
    public function execute($image)
    {
        $diameter = $this->argument(0)->type('numeric')->required()->value();
        $x = $this->argument(1)->type('numeric')->required()->value();
        $y = $this->argument(2)->type('numeric')->required()->value();
        $callback = $this->argument(3)->type('closure')->value();

        $circle_classname = sprintf('\Intervention\Image\%s\Shapes\CircleShape',
            $image->getDriver()->getDriverName());

        $circle = new $circle_classname($diameter);

        if ($callback instanceof Closure) {
            $callback($circle);
        }

        $circle->applyToImage($image, $x, $y);

        return true;
    }
}


code:
<?php

namespace Intervention\Image\Commands;

use Closure;

class EllipseCommand extends AbstractCommand
{
    /**
     * Draws ellipse on given image
     *
     * @param  \Intervention\Image\Image $image
     * @return boolean
     */
    public function execute($image)
    {
        $width = $this->argument(0)->type('numeric')->required()->value();
        $height = $this->argument(1)->type('numeric')->required()->value();
        $x = $this->argument(2)->type('numeric')->required()->value();
        $y = $this->argument(3)->type('numeric')->required()->value();
        $callback = $this->argument(4)->type('closure')->value();

        $ellipse_classname = sprintf('\Intervention\Image\%s\Shapes\EllipseShape',
            $image->getDriver()->getDriverName());

        $ellipse = new $ellipse_classname($width, $height);

        if ($callback instanceof Closure) {
            $callback($ellipse);
        }

        $ellipse->applyToImage($image, $x, $y);

        return true;
    }
}


code:
<?php

namespace Intervention\Image\Commands;

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

class ExifCommand extends AbstractCommand
{
    /**
     * Read Exif data from the given image
     *
     * Note: Windows PHP Users - in order to use this method you will need to
     * enable the mbstring and exif extensions within the php.ini file.
     *
     * @param  \Intervention\Image\Image $image
     * @return boolean
     */
    public function execute($image)
    {
        if (!function_exists('exif_read_data')) {
            throw new NotSupportedException(
                "Reading Exif data is not supported by this PHP installation."
            );
        }

        $key = $this->argument(0)->value();

        // try to read exif data from image file
        try {
            $data = @exif_read_data($image->dirname . '/' . $image->basename);

            if (!is_null($key) && is_array($data)) {
                $data = array_key_exists($key, $data) ? $data[$key] : false;
            }

        } catch (\Exception $e) {
            throw new NotReadableException(
                sprintf(
                    "Cannot read the Exif data from the filename (%s) provided ",
                    $image->dirname . '/' . $image->basename
                ),
                $e->getCode(),
                $e
            );
        }

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


code:
<?php

namespace Intervention\Image\Commands;

use Intervention\Image\Exception\NotSupportedException;

class IptcCommand extends AbstractCommand
{
    /**
     * Read Iptc data from the given image
     *
     * @param  \Intervention\Image\Image $image
     * @return boolean
     */
    public function execute($image)
    {
        if ( ! function_exists('iptcparse')) {
            throw new NotSupportedException(
                "Reading Iptc data is not supported by this PHP installation."
            );
        }

        $key = $this->argument(0)->value();

        $info = [];
        @getimagesize($image->dirname .'/'. $image->basename, $info);

        $data = [];

        if (array_key_exists('APP13', $info)) {
            $iptc = iptcparse($info['APP13']);

            if (is_array($iptc)) {
                $data['DocumentTitle'] = isset($iptc["2#005"][0]) ? $iptc["2#005"][0] : null;
                $data['Urgency'] = isset($iptc["2#010"][0]) ? $iptc["2#010"][0] : null;
                $data['Category'] = isset($iptc["2#015"][0]) ? $iptc["2#015"][0] : null;
                $data['Subcategories'] = isset($iptc["2#020"][0]) ? $iptc["2#020"][0] : null;
                $data['Keywords'] = isset($iptc["2#025"][0]) ? $iptc["2#025"] : null;
                $data['SpecialInstructions'] = isset($iptc["2#040"][0]) ? $iptc["2#040"][0] : null;
                $data['CreationDate'] = isset($iptc["2#055"][0]) ? $iptc["2#055"][0] : null;
                $data['CreationTime'] = isset($iptc["2#060"][0]) ? $iptc["2#060"][0] : null;
                $data['AuthorByline'] = isset($iptc["2#080"][0]) ? $iptc["2#080"][0] : null;
                $data['AuthorTitle'] = isset($iptc["2#085"][0]) ? $iptc["2#085"][0] : null;
                $data['City'] = isset($iptc["2#090"][0]) ? $iptc["2#090"][0] : null;
                $data['SubLocation'] = isset($iptc["2#092"][0]) ? $iptc["2#092"][0] : null;
                $data['State'] = isset($iptc["2#095"][0]) ? $iptc["2#095"][0] : null;
                $data['Country'] = isset($iptc["2#101"][0]) ? $iptc["2#101"][0] : null;
                $data['OTR'] = isset($iptc["2#103"][0]) ? $iptc["2#103"][0] : null;
                $data['Headline'] = isset($iptc["2#105"][0]) ? $iptc["2#105"][0] : null;
                $data['Source'] = isset($iptc["2#110"][0]) ? $iptc["2#110"][0] : null;
                $data['PhotoSource'] = isset($iptc["2#115"][0]) ? $iptc["2#115"][0] : null;
                $data['Copyright'] = isset($iptc["2#116"][0]) ? $iptc["2#116"][0] : null;
                $data['Caption'] = isset($iptc["2#120"][0]) ? $iptc["2#120"][0] : null;
                $data['CaptionWriter'] = isset($iptc["2#122"][0]) ? $iptc["2#122"][0] : null;
            }
        }

        if (! is_null($key) && is_array($data)) {
            $data = array_key_exists($key, $data) ? $data[$key] : false;
        }

        $this->setOutput($data);

        return true;
    }
}


code:
<?php

namespace Intervention\Image\Commands;

use Closure;

class LineCommand extends AbstractCommand
{
    /**
     * Draws line on given image
     *
     * @param  \Intervention\Image\Image $image
     * @return boolean
     */
    public function execute($image)
    {
        $x1 = $this->argument(0)->type('numeric')->required()->value();
        $y1 = $this->argument(1)->type('numeric')->required()->value();
        $x2 = $this->argument(2)->type('numeric')->required()->value();
        $y2 = $this->argument(3)->type('numeric')->required()->value();
        $callback = $this->argument(4)->type('closure')->value();

        $line_classname = sprintf('\Intervention\Image\%s\Shapes\LineShape',
            $image->getDriver()->getDriverName());

        $line = new $line_classname($x2, $y2);

        if ($callback instanceof Closure) {
            $callback($line);
        }

        $line->applyToImage($image, $x1, $y1);

        return true;
    }
}


code:
<?php

namespace Intervention\Image\Commands;

class OrientateCommand extends AbstractCommand
{
    /**
     * Correct image orientation according to Exif data
     *
     * @param  \Intervention\Image\Image $image
     * @return boolean
     */
    public function execute($image)
    {
        switch ($image->exif('Orientation')) {

            case 2:
                $image->flip();
                break;

            case 3:
                $image->rotate(180);
                break;

            case 4:
                $image->rotate(180)->flip();
                break;

            case 5:
                $image->rotate(270)->flip();
                break;

            case 6:
                $image->rotate(270);
                break;

            case 7:
                $image->rotate(90)->flip();
                break;

            case 8:
                $image->rotate(90);
                break;
        }

        return true;
    }
}


code:
<?php

namespace Intervention\Image\Commands;

use Closure;
use Intervention\Image\Exception\InvalidArgumentException;

class PolygonCommand extends AbstractCommand
{
    /**
     * Draw a polygon on given image
     *
     * @param  \Intervention\Image\image $image
     * @return boolean
     */
    public function execute($image)
    {
        $points = $this->argument(0)->type('array')->required()->value();
        $callback = $this->argument(1)->type('closure')->value();

        $vertices_count = count($points);

        // check if number if coordinates is even
        if ($vertices_count % 2 !== 0) {
            throw new InvalidArgumentException(
                "The number of given polygon vertices must be even."
            );
        }

        if ($vertices_count < 6) {
            throw new InvalidArgumentException(
                "You must have at least 3 points in your array."
            );
        }

        $polygon_classname = sprintf('\Intervention\Image\%s\Shapes\PolygonShape',
            $image->getDriver()->getDriverName());

        $polygon = new $polygon_classname($points);

        if ($callback instanceof Closure) {
            $callback($polygon);
        }

        $polygon->applyToImage($image);

        return true;
    }
}


code:
<?php

namespace Intervention\Image\Commands;

use GuzzleHttp\Psr7\Response;

class PsrResponseCommand extends AbstractCommand
{
    /**
     * Builds PSR7 compatible response. May replace "response" command in
     * some future.
     *
     * Method will generate binary stream and put it inside PSR-7
     * ResponseInterface. Following code can be optimized using native php
     * streams and more "clean" streaming, however drivers has to be updated
     * first.
     *
     * @param  \Intervention\Image\Image $image
     * @return boolean
     */
    public function execute($image)
    {
        $format = $this->argument(0)->value();
        $quality = $this->argument(1)->between(0, 100)->value();

        //Encoded property will be populated at this moment
        $stream = $image->stream($format, $quality);

        $mimetype = finfo_buffer(
            finfo_open(FILEINFO_MIME_TYPE),
            $image->getEncoded()
        );

        $this->setOutput(new Response(
            200,
            [
                'Content-Type'   => $mimetype,
                'Content-Length' => strlen($image->getEncoded())
            ],
            $stream
        ));

        return true;
    }
}


code:
<?php

namespace Intervention\Image\Commands;

use Closure;

class RectangleCommand extends AbstractCommand
{
    /**
     * Draws rectangle on given image
     *
     * @param  \Intervention\Image\Image $image
     * @return boolean
     */
    public function execute($image)
    {
        $x1 = $this->argument(0)->type('numeric')->required()->value();
        $y1 = $this->argument(1)->type('numeric')->required()->value();
        $x2 = $this->argument(2)->type('numeric')->required()->value();
        $y2 = $this->argument(3)->type('numeric')->required()->value();
        $callback = $this->argument(4)->type('closure')->value();

        $rectangle_classname = sprintf('\Intervention\Image\%s\Shapes\RectangleShape',
            $image->getDriver()->getDriverName());

        $rectangle = new $rectangle_classname($x1, $y1, $x2, $y2);

        if ($callback instanceof Closure) {
            $callback($rectangle);
        }

        $rectangle->applyToImage($image, $x1, $y1);

        return true;
    }
}


code:
<?php

namespace Intervention\Image\Commands;

use Intervention\Image\Response;

class ResponseCommand extends AbstractCommand
{
    /**
     * Builds HTTP response from given image
     *
     * @param  \Intervention\Image\Image $image
     * @return boolean
     */
    public function execute($image)
    {
        $format = $this->argument(0)->value();
        $quality = $this->argument(1)->between(0, 100)->value();

        $response = new Response($image, $format, $quality);

        $this->setOutput($response->make());

        return true;
    }
}


code:
<?php

namespace Intervention\Image\Commands;

class StreamCommand extends AbstractCommand
{
    /**
     * Builds PSR7 stream based on image data. Method uses Guzzle PSR7
     * implementation as easiest choice.
     *
     * @param  \Intervention\Image\Image $image
     * @return boolean
     */
    public function execute($image)
    {
        $format = $this->argument(0)->value();
        $quality = $this->argument(1)->between(0, 100)->value();

        $this->setOutput(\GuzzleHttp\Psr7\stream_for(
            $image->encode($format, $quality)->getEncoded()
        ));

        return true;
    }
}


code:
<?php

namespace Intervention\Image\Commands;

use Closure;

class TextCommand extends AbstractCommand
{
    /**
     * Write text on given image
     * @param  \Intervention\Image\Image $image
     * @return boolean
     */
    public function execute($image)
    {
        $text = $this->argument(0)->required()->value();
        $x = $this->argument(1)->type('numeric')->value(0);
        $y = $this->argument(2)->type('numeric')->value(0);
        $callback = $this->argument(3)->type('closure')->value();

        $fontclassname = sprintf('\Intervention\Image\%s\Font',
            $image->getDriver()->getDriverName());

        $font = new $fontclassname($text);

        if ($callback instanceof Closure) {
            $callback($font);
        }

        $font->applyToImage($image, $x, $y);

        return true;
    }
}


code:
<?php

namespace Intervention\Image;

class Constraint
{
    /**
     * Bit value of aspect ratio constraint
     */
    const ASPECTRATIO = 1;

    /**
     * Bit value of upsize constraint
     */
    const UPSIZE = 2;

    /**
     * Constraint size
     *
     * @var \Intervention\Image\Size
     */
    private $size;

    /**
     * Integer value of fixed parameters
     *
     * @var int
     */
    private $fixed = 0;

    /**
     * Create a new constraint based on size
     *
     * @param Size $size
     */
    public function __construct(Size $size)
    {
        $this->size = $size;
    }

    /**
     * Returns current size of constraint
     *
     * @return \Intervention\Image\Size
     */
    public function getSize()
    {
        return $this->size;
    }

    /**
     * Fix the given argument in current constraint
     *
     * @param  int $type
     * @return void
     */
    public function fix($type)
    {
        $this->fixed = ($this->fixed & ~(1 << $type)) | (1 << $type);
    }

    /**
     * Checks if given argument is fixed in current constraint
     *
     * @param  int  $type
     * @return boolean
     */
    public function isFixed($type)
    {
        return (bool) ($this->fixed & (1 << $type));
    }

    /**
     * Fixes aspect ratio in current constraint
     *
     * @return void
     */
    public function aspectRatio()
    {
        $this->fix(self::ASPECTRATIO);
    }

    /**
     * Fixes possibility to size up in current constraint
     *
     * @return void
     */
    public function upsize()
    {
        $this->fix(self::UPSIZE);
    }
}


code:
<?php

namespace Intervention\Image\Exception;

class ImageException extends \RuntimeException
{
    # nothing to override
}


code:
<?php

namespace Intervention\Image\Exception;

class InvalidArgumentException extends ImageException
{
    # nothing to override
}


code:
<?php

namespace Intervention\Image\Exception;

class MissingDependencyException extends ImageException
{
    # nothing to override
}


code:
<?php

namespace Intervention\Image\Exception;

class NotFoundException extends ImageException
{
    # nothing to override
}


code:
<?php

namespace Intervention\Image\Exception;

class NotReadableException extends ImageException
{
    # nothing to override
}


code:
<?php

namespace Intervention\Image\Exception;

class NotSupportedException extends ImageException
{
    # nothing to override
}


code:
<?php

namespace Intervention\Image\Exception;

class NotWritableException extends ImageException
{
    # nothing to override
}


code:
<?php

namespace Intervention\Image\Exception;

class RuntimeException extends ImageException
{
    # nothing to override
}


code:
<?php

namespace Intervention\Image\Facades;

use Illuminate\Support\Facades\Facade;

/**
 * @method static \Intervention\Image\Image make(mixed $data)
 * @method static self configure(array $config)
 * @method static \Intervention\Image\Image canvas(int $width, int $height, mixed $background = null)
 * @method static \Intervention\Image\Image cache(\Closure $callback, int $lifetime = null, boolean $returnObj = false)
 */
class Image extends Facade
{
    protected static function getFacadeAccessor()
    {
        return 'image';
    }
}


code:
<?php

namespace Intervention\Image;

class File
{
    /**
     * Mime type
     *
     * @var string
     */
    public $mime;

    /**
     * Name of directory path
     *
     * @var string
     */
    public $dirname;

    /**
     * Basename of current file
     *
     * @var string
     */
    public $basename;

    /**
     * File extension of current file
     *
     * @var string
     */
    public $extension;

    /**
     * File name of current file
     *
     * @var string
     */
    public $filename;

    /**
     * Sets all instance properties from given path
     *
     * @param string $path
     */
    public function setFileInfoFromPath($path)
    {
        $info = pathinfo($path);
        $this->dirname = array_key_exists('dirname', $info) ? $info['dirname'] : null;
        $this->basename = array_key_exists('basename', $info) ? $info['basename'] : null;
        $this->extension = array_key_exists('extension', $info) ? $info['extension'] : null;
        $this->filename = array_key_exists('filename', $info) ? $info['filename'] : null;

        if (file_exists($path) && is_file($path)) {
            $this->mime = finfo_file(finfo_open(FILEINFO_MIME_TYPE), $path);
        }

        return $this;
    }

     /**
      * Get file size
      *
      * @return mixed
      */
    public function filesize()
    {
        $path = $this->basePath();

        if (file_exists($path) && is_file($path)) {
            return filesize($path);
        }

        return false;
    }

    /**
     * Get fully qualified path
     *
     * @return string
     */
    public function basePath()
    {
        if ($this->dirname && $this->basename) {
            return ($this->dirname .'/'. $this->basename);
        }

        return null;
    }

}


code:
<?php

namespace Intervention\Image\Filters;

use Intervention\Image\Image;

class DemoFilter implements FilterInterface
{
    /**
     * Default size of filter effects
     */
    const DEFAULT_SIZE = 10;

    /**
     * Size of filter effects
     *
     * @var int
     */
    private $size;

    /**
     * Creates new instance of filter
     *
     * @param int $size
     */
    public function __construct($size = null)
    {
        $this->size = is_numeric($size) ? intval($size) : self::DEFAULT_SIZE;
    }

    /**
     * Applies filter effects to given image
     *
     * @param  \Intervention\Image\Image $image
     * @return \Intervention\Image\Image
     */
    public function applyFilter(Image $image)
    {
        $image->pixelate($this->size);
        $image->greyscale();

        return $image;
    }
}


code:
<?php

namespace Intervention\Image\Filters;

use Intervention\Image\Image;

interface FilterInterface
{
    /**
     * Applies filter to given image
     *
     * @param  \Intervention\Image\Image $image
     * @return \Intervention\Image\Image
     */
    public function applyFilter(Image $image);
}


code:
<?php

namespace Intervention\Image\Gd;

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

class Color extends AbstractColor
{
    /**
     * RGB Red value of current color instance
     *
     * @var int
     */
    public $r;

    /**
     * RGB Green value of current color instance
     *
     * @var int
     */
    public $g;

    /**
     * RGB Blue value of current color instance
     *
     * @var int
     */
    public $b;

    /**
     * RGB Alpha value of current color instance
     *
     * @var float
     */
    public $a;

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

    /**
     * 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;
            $this->a = $this->alpha2gd($a);

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

            // color array without alpha value
            list($r, $g, $b) = $array;
            $this->a = 0;

        }

        $this->r = $r;
        $this->g = $g;
        $this->b = $b;
    }

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

    /**
     * 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->r = intval($r);
        $this->g = intval($g);
        $this->b = intval($b);
        $this->a = 0;
    }

    /**
     * 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 = 1)
    {
        $this->r = intval($r);
        $this->g = intval($g);
        $this->b = intval($b);
        $this->a = $this->alpha2gd($a);
    }

    /**
     * Initiates color object from given ImagickPixel object
     *
     * @param  ImagickPixel $value
     * @return \Intervention\Image\AbstractColor
     */
    public function initFromObject($value)
    {
        throw new NotSupportedException(
            "GD colors cannot init from ImagickPixel objects."
        );
    }

    /**
     * Calculates integer value of current color instance
     *
     * @return int
     */
    public function getInt()
    {
        return ($this->a << 24) + ($this->r << 16) + ($this->g << 8) + $this->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->r, $this->g, $this->b);
    }

    /**
     * Calculates RGB(A) in array format of current color instance
     *
     * @return array
     */
    public function getArray()
    {
        return [$this->r, $this->g, $this->b, round(1 - $this->a / 127, 2)];
    }

    /**
     * Calculates RGBA in string format of current color instance
     *
     * @return string
     */
    public function getRgba()
    {
        return sprintf('rgba(%d, %d, %d, %.2F)', $this->r, $this->g, $this->b, round(1 - $this->a / 127, 2));
    }

    /**
     * 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 * 1.27);

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

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

    /**
     * Convert rgba alpha (0-1) value to gd value (0-127)
     *
     * @param  float $input
     * @return int
     */
    private function alpha2gd($input)
    {
        $oldMin = 0;
        $oldMax = 1;

        $newMin = 127;
        $newMax = 0;

        return ceil(((($input- $oldMin) * ($newMax - $newMin)) / ($oldMax - $oldMin)) + $newMin);
    }
}


code:
<?php

namespace Intervention\Image\Gd\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\Gd\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);

        for ($i=0; $i < intval($amount); $i++) {
            imagefilter($image->getCore(), IMG_FILTER_GAUSSIAN_BLUR);
        }

        return true;
    }
}


code:
<?php

namespace Intervention\Image\Gd\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 imagefilter($image->getCore(), IMG_FILTER_BRIGHTNESS, ($level * 2.55));
    }
}


code:
<?php

namespace Intervention\Image\Gd\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 = round($red * 2.55);
        $green = round($green * 2.55);
        $blue = round($blue * 2.55);

        // apply filter
        return imagefilter($image->getCore(), IMG_FILTER_COLORIZE, $red, $green, $blue);
    }
}


code:
<?php

namespace Intervention\Image\Gd\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 imagefilter($image->getCore(), IMG_FILTER_CONTRAST, ($level * -1));
    }
}


code:
<?php

namespace Intervention\Image\Gd\Commands;

use Intervention\Image\Point;
use Intervention\Image\Size;

class CropCommand extends ResizeCommand
{
    /**
     * 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 \Intervention\Image\Exception\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
        return $this->modify($image, 0, 0, $position->x, $position->y, $cropped->width, $cropped->height, $cropped->width, $cropped->height);
    }
}


code:
<?php

namespace Intervention\Image\Gd\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
        imagedestroy($image->getCore());

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

        return true;
    }
}


code:
<?php

namespace Intervention\Image\Gd\Commands;

use Intervention\Image\Commands\AbstractCommand;
use Intervention\Image\Gd\Color;
use Intervention\Image\Gd\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();

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

        try {

            // set image tile filling
            $source = new Decoder;
            $tile = $source->init($filling);
            imagesettile($image->getCore(), $tile->getCore());
            $filling = IMG_COLOR_TILED;

        } catch (\Intervention\Image\Exception\NotReadableException $e) {

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

        imagealphablending($resource, true);

        if (is_int($x) && is_int($y)) {

            // resource should be visible through transparency
            $base = $image->getDriver()->newImage($width, $height)->getCore();
            imagecopy($base, $resource, 0, 0, 0, 0, $width, $height);

            // floodfill if exact position is defined
            imagefill($resource, $x, $y, $filling);

            // copy filled original over base
            imagecopy($base, $resource, 0, 0, 0, 0, $width, $height);

            // set base as new resource-core
            $image->setCore($base);
            imagedestroy($resource);

        } else {
            // fill whole image otherwise
            imagefilledrectangle($resource, 0, 0, $width - 1, $height - 1, $filling);
        }

        isset($tile) ? imagedestroy($tile->getCore()) : null;

        return true;
    }
}


code:
<?php

namespace Intervention\Image\Gd\Commands;

use Intervention\Image\Size;

class FitCommand extends ResizeCommand
{
    /**
     * 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);

        // modify image
        $this->modify($image, 0, 0, $cropped->pivot->x, $cropped->pivot->y, $resized->getWidth(), $resized->getHeight(), $cropped->getWidth(), $cropped->getHeight());

        return true;
    }
}


code:
<?php

namespace Intervention\Image\Gd\Commands;

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

        $size = $image->getSize();
        $dst = clone $size;

        switch (strtolower($mode)) {
            case 2:
            case 'v':
            case 'vert':
            case 'vertical':
                $size->pivot->y = $size->height - 1;
                $size->height = $size->height * (-1);
                break;

            default:
                $size->pivot->x = $size->width - 1;
                $size->width = $size->width * (-1);
                break;
        }

        return $this->modify($image, 0, 0, $size->pivot->x, $size->pivot->y, $dst->width, $dst->height, $size->width, $size->height);
    }
}


code:
<?php

namespace Intervention\Image\Gd\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 imagegammacorrect($image->getCore(), 1, $gamma);
    }
}


code:
<?php

namespace Intervention\Image\Gd\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)
    {
        $this->setOutput(new Size(
            imagesx($image->getCore()),
            imagesy($image->getCore())
        ));

        return true;
    }
}


code:
<?php

namespace Intervention\Image\Gd\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 imagefilter($image->getCore(), IMG_FILTER_GRAYSCALE);
    }
}


code:
<?php

namespace Intervention\Image\Gd\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\Gd\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
        imagealphablending($image->getCore(), true);
        return imagecopy($image->getCore(), $watermark->getCore(), $target->x, $target->y, 0, 0, $watermark_size->width, $watermark_size->height);
    }
}


code:
<?php

namespace Intervention\Image\Gd\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);

        imageinterlace($image->getCore(), $mode);

        return true;
    }
}


code:
<?php

namespace Intervention\Image\Gd\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 imagefilter($image->getCore(), IMG_FILTER_NEGATE);
    }
}


code:
<?php

namespace Intervention\Image\Gd\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();

        // create empty canvas
        $resource = imagecreatetruecolor($size->width, $size->height);

        // define matte
        if (is_null($matte)) {
            $matte = imagecolorallocatealpha($resource, 255, 255, 255, 127);
        } else {
            $matte = $image->getDriver()->parseColor($matte)->getInt();
        }

        // fill with matte and copy original image
        imagefill($resource, 0, 0, $matte);

        // set transparency
        imagecolortransparent($resource, $matte);

        // copy original image
        imagecopy($resource, $image->getCore(), 0, 0, 0, 0, $size->width, $size->height);

        if (is_numeric($count) && $count <= 256) {
            // decrease colors
            imagetruecolortopalette($resource, true, $count);
        }

        // set new resource
        $image->setCore($resource);

        return true;
    }
}


code:
<?php

namespace Intervention\Image\Gd\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);

        $image_size = $image->getSize();

        // create empty canvas
        $canvas = $image->getDriver()->newImage($image_size->width, $image_size->height, [0,0,0,0]);

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

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

        imagealphablending($canvas->getCore(), false);

        if ( ! $mask_w_alpha) {
            // mask from greyscale image
            imagefilter($mask->getCore(), IMG_FILTER_GRAYSCALE);
        }

        // redraw old image pixel by pixel considering alpha map
        for ($x=0; $x < $image_size->width; $x++) {
            for ($y=0; $y < $image_size->height; $y++) {

                $color = $image->pickColor($x, $y, 'array');
                $alpha = $mask->pickColor($x, $y, 'array');

                if ($mask_w_alpha) {
                    $alpha = $alpha[3]; // use alpha channel as mask
                } else {

                    if ($alpha[3] == 0) { // transparent as black
                        $alpha = 0;
                    } else {

                        // $alpha = floatval(round((($alpha[0] + $alpha[1] + $alpha[3]) / 3) / 255, 2));

                        // image is greyscale, so channel doesn't matter (use red channel)
                        $alpha = floatval(round($alpha[0] / 255, 2));
                    }

                }

                // preserve alpha of original image...
                if ($color[3] < $alpha) {
                    $alpha = $color[3];
                }

                // replace alpha value
                $color[3] = $alpha;

                // redraw pixel
                $canvas->pixel($color, $x, $y);
            }
        }

        // replace current image with masked instance
        $image->setCore($canvas->getCore());

        return true;
    }
}


code:
<?php

namespace Intervention\Image\Gd\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();

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

        // build temp alpha mask
        $mask_color = sprintf('rgba(0, 0, 0, %.1F)', $transparency / 100);
        $mask = $image->getDriver()->newImage($size->width, $size->height, $mask_color);

        // mask image
        $image->mask($mask->getCore(), true);

        return true;
    }
}


code:
<?php

namespace Intervention\Image\Gd\Commands;

use Intervention\Image\Commands\AbstractCommand;
use Intervention\Image\Gd\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 = imagecolorat($image->getCore(), $x, $y);

        if ( ! imageistruecolor($image->getCore())) {
            $color = imagecolorsforindex($image->getCore(), $color);
            $color['alpha'] = round(1 - $color['alpha'] / 127, 2);
        }

        $color = new Color($color);

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

        return true;
    }
}


code:
<?php

namespace Intervention\Image\Gd\Commands;

use Intervention\Image\Commands\AbstractCommand;
use Intervention\Image\Gd\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();

        return imagesetpixel($image->getCore(), $x, $y, $color->getInt());
    }
}


code:
<?php

namespace Intervention\Image\Gd\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);

        return imagefilter($image->getCore(), IMG_FILTER_PIXELATE, $size, true);
    }
}


code:
<?php

namespace Intervention\Image\Gd\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();

        if (is_resource($backup = $image->getBackup($backupName))) {

            // destroy current resource
            imagedestroy($image->getCore());

            // clone backup
            $backup = $image->getDriver()->cloneCore($backup);

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

            return true;
        }

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


code:
<?php

namespace Intervention\Image\Gd\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
        $transparent = imagecolorallocatealpha($canvas->getCore(), 255, 255, 255, 127);
        imagealphablending($canvas->getCore(), false); // do not blend / just overwrite
        imagefilledrectangle($canvas->getCore(), $dst_x, $dst_y, $dst_x + $src_w - 1, $dst_y + $src_h - 1, $transparent);

        // copy image into new canvas
        imagecopy($canvas->getCore(), $image->getCore(), $dst_x, $dst_y, $src_x, $src_y, $src_w, $src_h);

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

        return true;
    }
}


code:
<?php

namespace Intervention\Image\Gd\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
        $this->modify($image, 0, 0, 0, 0, $resized->getWidth(), $resized->getHeight(), $image->getWidth(), $image->getHeight());

        return true;
    }

    /**
     * Wrapper function for 'imagecopyresampled'
     *
     * @param  Image   $image
     * @param  int     $dst_x
     * @param  int     $dst_y
     * @param  int     $src_x
     * @param  int     $src_y
     * @param  int     $dst_w
     * @param  int     $dst_h
     * @param  int     $src_w
     * @param  int     $src_h
     * @return boolean
     */
    protected function modify($image, $dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h)
    {
        // create new image
        $modified = imagecreatetruecolor($dst_w, $dst_h);

        // get current image
        $resource = $image->getCore();

        // preserve transparency
        $transIndex = imagecolortransparent($resource);

        if ($transIndex != -1) {
            $rgba = imagecolorsforindex($modified, $transIndex);
            $transColor = imagecolorallocatealpha($modified, $rgba['red'], $rgba['green'], $rgba['blue'], 127);
            imagefill($modified, 0, 0, $transColor);
            imagecolortransparent($modified, $transColor);
        } else {
            imagealphablending($modified, false);
            imagesavealpha($modified, true);
        }

        // copy content from resource
        $result = imagecopyresampled(
            $modified,
            $resource,
            $dst_x,
            $dst_y,
            $src_x,
            $src_y,
            $dst_w,
            $dst_h,
            $src_w,
            $src_h
        );

        // set new content as recource
        $image->setCore($modified);

        return $result;
    }
}


code:
<?php

namespace Intervention\Image\Gd\Commands;

use Intervention\Image\Commands\AbstractCommand;
use Intervention\Image\Gd\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->setCore(imagerotate($image->getCore(), $angle, $color->getInt()));

        return true;
    }
}


code:
<?php

namespace Intervention\Image\Gd\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);

        // build matrix
        $min = $amount >= 10 ? $amount * -0.01 : 0;
        $max = $amount * -0.025;
        $abs = ((4 * $min + 4 * $max) * -1) + 1;
        $div = 1;

        $matrix = [
            [$min, $max, $min],
            [$max, $abs, $max],
            [$min, $max, $min]
        ];

        // apply the matrix
        return imageconvolution($image->getCore(), $matrix, $div, 0);
    }
}


code:
<?php

namespace Intervention\Image\Gd\Commands;

use Intervention\Image\Gd\Color;

class TrimCommand extends ResizeCommand
{
    /**
     * 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();

        // default values
        $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) {
            $color = new Color; // color will only be used to compare alpha channel
        } else {
            $color = $image->pickColor($base_x, $base_y, 'object');
        }

        $top_x = 0;
        $top_y = 0;
        $bottom_x = $width;
        $bottom_y = $height;

        // search upper part of image for colors to trim away
        if (in_array('top', $away)) {

            for ($y=0; $y < ceil($height/2); $y++) {
                for ($x=0; $x < $width; $x++) {

                    $checkColor = $image->pickColor($x, $y, 'object');

                    if ($checkTransparency) {
                        $checkColor->r = $color->r;
                        $checkColor->g = $color->g;
                        $checkColor->b = $color->b;
                    }

                    if ($color->differs($checkColor, $tolerance)) {
                        $top_y = max(0, $y - $feather);
                        break 2;
                    }

                }
            }

        }

        // search left part of image for colors to trim away
        if (in_array('left', $away)) {

            for ($x=0; $x < ceil($width/2); $x++) {
                for ($y=$top_y; $y < $height; $y++) {

                    $checkColor = $image->pickColor($x, $y, 'object');

                    if ($checkTransparency) {
                        $checkColor->r = $color->r;
                        $checkColor->g = $color->g;
                        $checkColor->b = $color->b;
                    }

                    if ($color->differs($checkColor, $tolerance)) {
                        $top_x = max(0, $x - $feather);
                        break 2;
                    }

                }
            }

        }

        // search lower part of image for colors to trim away
        if (in_array('bottom', $away)) {

            for ($y=($height-1); $y >= floor($height/2)-1; $y--) {
                for ($x=$top_x; $x < $width; $x++) {

                    $checkColor = $image->pickColor($x, $y, 'object');

                    if ($checkTransparency) {
                        $checkColor->r = $color->r;
                        $checkColor->g = $color->g;
                        $checkColor->b = $color->b;
                    }

                    if ($color->differs($checkColor, $tolerance)) {
                        $bottom_y = min($height, $y+1 + $feather);
                        break 2;
                    }

                }
            }

        }

        // search right part of image for colors to trim away
        if (in_array('right', $away)) {

            for ($x=($width-1); $x >= floor($width/2)-1; $x--) {
                for ($y=$top_y; $y < $bottom_y; $y++) {

                    $checkColor = $image->pickColor($x, $y, 'object');

                    if ($checkTransparency) {
                        $checkColor->r = $color->r;
                        $checkColor->g = $color->g;
                        $checkColor->b = $color->b;
                    }

                    if ($color->differs($checkColor, $tolerance)) {
                        $bottom_x = min($width, $x+1 + $feather);
                        break 2;
                    }

                }
            }

        }

        // trim parts of image
        return $this->modify($image, 0, 0, $top_x, $top_y, ($bottom_x-$top_x), ($bottom_y-$top_y), ($bottom_x-$top_x), ($bottom_y-$top_y));

    }
}


code:
<?php

namespace Intervention\Image\Gd\Commands;

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

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

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