Manipulação De Imagens Implementando uma GDLib com OO

Na minha longa jornada reconstruindo minha base de trabalho, utilizando padrões de projeto, cheguei à manipulação de imagens.
O PHP possui a excelente biblioteca GD habilitada por padrão na maioria dos servidores.

Como nem tudo são flores, quem já utilizou a GD nota que ela é um tanto 'verbosa'. Seus métodos possuem listas intermináveis de argumentos, muitas vezes numa ordem não intuitiva.
Para resolver esse problema, eu apenas comecei uma implementação OO da GD, falta bastante coisa, mas o basicão está aqui:

Primeiramente, as estruturas necessárias para a implementação:
Image

/**
 * Representa uma imagem salva
 */
class Image {
        /**
     * @property string $path : o caminho para a imagem
     */
        private $path;
        
        /**
     * @property string $type : o mime-type da imagem
     */
        private $type;
        
        /**
     * @property int $width : a largura da imagem
     */
        private $width;
        
        /**
     * @property int $height: a altura da imagem
     */
        private $height;
        
        /**
     * Construtor 
     * @param string $path : o caminho para a imagem
     */
        public function __construct($path){
                if(!is_file($path))
                        throw new Exception('O arquivo de recurso não existe!');
                        
                $this->path = $path;
                $info = getimagesize($this->path);
                
                if(!preg_match('/(jpe?g)|(png)|(gif)|(bmp)$/', $info['mime']))
                        throw new Exception('O arquivo de recurso inválido!');
                
                $this->type = $info['mime'];
                $this->width = $info[0];
                $this->height = $info[1];
        }
        
        /**
     * Retorna a largura da imagem
     * @return int
     */
        public function getWidth(){
                return $this->width;
        }

        /**
     * Retorna a altura da imagem
     * @return int
     */
        public function getHeight(){
                return $this->height;
        }
        
        /**
     * Retorna o tipo da imagem
     * @return string
     */
        public function getType(){
                return $this->type;
        }
        
        /**
     * Retorna o caminho para a imagem
     * @return string
     */
        public function getPath(){
                return $this->path;
        }
}


Point
/*
 * Classe Point implementa um ponto em R^2
 */
class Point {
        private $x, $y;
        
        public function __construct($x = 0, $y = 0){
                $this->x = (float) $x;
                $this->y = (float) $y;
        }
        
        /*
     * Os métodos setters utilizam-se de fluent interface, 
     * retornando o ponteiro para o próprio objeto, afim
     * de ser possível o encadeamento de métodos.
     * Ex.:
     *  $a = new Point();
     *  $a->setX(3)->setY(4);
     */
        
        /**
     * Seta a coordenada X
     * @param $x
     * @return pointer
     */
        public function setX($x) {
                $this->x = (float) $x;
                return $this;
        }
        
        /**
     * Seta a coordenada Y
     * @param $x
     * @return pointer
     */
        public function setY($y) {
                $this->y = (float) $y;
                return $this;
        }
        
        /**
     * Retorna o valor da coordenada X
     * @return float
     */
        public function getX(){
                return $this->x;
        }
        
        /**
     * Retorna o valor da coordenada Y
     * @return float
     */
        public function getY(){
                return $this->y;
        }
}


RGBColor
/*
 * Representa uma Cor RGB
 */
class RGBColor {
        /**
     * @property int $R, int $G, int $B : representam respectivamente os valores de Vermelho, Verde e Azul da cor  
     */
        protected $R, $G, $B;
        
        public function __construct($R = 255, $G = 255, $B = 255){
                $this->R = (int) $R;
                $this->G = (int) $G;
                $this->B = (int) $B;
        }
        
        final public function setR($R){
                $this->R = (int) $R;
                return $this;
        }
        
        final public function setG($G){
                $this->G = (int) $G;
                return $this;
        }
        
        final public function setB($B){
                $this->B = (int) $B;
                return $this;
        }
        
        final public function getR(){
                return $this->R;
        }
        
        final public function getG(){
                return $this->G;
        }
        
        final public function getB(){
                return $this->B;
        }
        
        /**
     * Converte a cor para sua representação hexadecimal
     * @return int
     */
        public function toHex(){
                $R = str_pad(base_convert($this->R, 10, 16), 2, 0, STR_PAD_LEFT);
                $G = str_pad(base_convert($this->G, 10, 16), 2, 0, STR_PAD_LEFT);
                $B = str_pad(base_convert($this->B, 10, 16), 2, 0, STR_PAD_LEFT);
                
                return sprintf('0x%s%s%s', $R, $G, $B);
        }
}


RGBAColor
/*
 * Implementa uma cor com canal alpha de transparência
 */
final class RGBAColor extends RGBColor {
        /**
     * @var int $alpha : a opacitade (canal alpha) da imagem
     */
        private $alpha;
        public function __construct($R = 255, $G = 255, $B = 255, $alpha = 100){
                $this->R = $R;
                $this->G = $G;
                $this->B = $B;
                $this->setAlpha($alpha);
        }
        
        public function setAlpha($alpha){
                $this->alpha = 127 - round(($alpha) * 127 / 100);
                return $this;
        }
        
        public function getAlpha(){
                return $this->alpha;
        }
        
        /**
     * @see RGBColor::toHex()
     */
        public function toHex(){
                $R = str_pad(base_convert($this->R, 10, 16), 2, 0, STR_PAD_LEFT);
                $G = str_pad(base_convert($this->G, 10, 16), 2, 0, STR_PAD_LEFT);
                $B = str_pad(base_convert($this->B, 10, 16), 2, 0, STR_PAD_LEFT);
                $alpha = str_pad(base_convert($this->alpha, 10, 16), 2, 0, STR_PAD_LEFT);
                
                return sprintf('0x%s%s%s%s', $alpha, $R, $G, $B);
        }
}


Os manipuladores
ImageAllocator
/*
 * Representação da imagem na memória principal
 */
class ImageAllocator {
        /**
     * @property resource : o recurso de imagem
     */
        private $resource;
        /**
     * @property ImageDecorator : objeto decorador de imagens
     */
        private $decorator;
        
        /**
     * Construtor implementado com polimorfismo
     * 2 assinaturas possíveis:
     * 
     *          ImageAllocator::ImageAllocator(Image $resource)
     *                  ->Cria a imagem a partir de um arquivo de imagem existente
     *          ImageAllocator::ImageAllocator(int $width, int $height)
     *                  ->Cria uma nova imagem na memória 
     */
        public function __construct(){
                $argv = func_get_args();
                $argc = count($argv);
                
                if($argc == 1){
                        if(!($argv[0] instanceof Image))
                                throw new Exception('Imagem de recurso inválida!');
                        
                        $this->loadResource($argv[0]);
                } else if($argc == 2){
                        $this->createResource((int) $argv[0], (int) $argv[1]);
                }
                
                $this->decorator = new ImageDecorator($this);
        }
        
        /**
     * Cria uma nova imagem na memória
     * @param $wdt : largura da imagem
     * @param $hgt : altura da imagem
     * @return void
     */
        private function createResource($wdt, $hgt){
                if($wdt <= 0 || $hgt <= 0)
                        throw new Exception(sprintf('Dimensões [%s, %s] inválidas para a alocação da imagem!', $wdt, $hgt));
                $this->resource = imagecreatetruecolor($wdt, $hgt);
        }
        
        /**
     * Carrega a imagem a partir de um arquivo de imagem existente
     * @param Image $source
     * @return void
     */
        private function loadResource(Image $source){
                $type = $source->getType();
                if(preg_match('/jpe?g$/', $type))
                        $this->resource = imagecreatefromjpeg($source->getPath());
                else if(preg_match('/gif$/', $type))
                        $this->resource = imagecreatefromgif($source->getPath());
                else if(preg_match('/png$/', $type))
                        $this->resource = imagecreatefrompng($source->getPath());
                else if(preg_match('/bmp$/', $type))
                        $this->resource = imagecreatefromwbmp($source->getPath());
                else
                        throw new Exception('O recurso não é uma imagem válida!');
        }
        
        /**
     * Fonece uma saída da imagem, para um arquivo ou para o navegador.
     * Se não queremos salvar um arquivos, apenas mostrá-lo no navegador,
     * configuramos $path apenas com o formato da imagem.
     * 
     * Exemplo:
     *          $img->output('jpeg') //fornece uma saída diretamente no navegador
     *          $img->output('arquivo.jpeg') //salva a imagem como 'arquivo.jpeg'
     * 
     * @param $path : caminho para salvar a imagem ou tipo de arquivo para exibir no navegador
     * @param $quality
     * @return ImageAllocator
     */
        public function output($path, $quality = 100){
                $explode = explode('.', $path);
                $type = end($explode);
                if(preg_match('/jpe?g$/', $type))
                        $f = 'imagejpeg';
                else if(preg_match('/gif$/', $type))
                        $f = 'imagegif';
                else if(preg_match('/png$/', $type))
                        $f = 'imagepng';
                else if(preg_match('/bmp$/', $type))
                        $f = 'imagewbmp';
                else
                        throw new Exception('Formato de saída inválido!');
                
                $q = ($f == 'imagepng') ? ($quality-10)/100 : $quality;
                $p = preg_match('/\./', $path) ? $path : null;
                call_user_func_array($f, array($this->resource, $p, $q));
                return $this;
        }
        
        /**
     * Retorna o decorador do objeto
     * @return ImageDecorator
     */
        public function getDecorator(){
                return $this->decorator;
        }
        
        /**
     * Retorna o recurso em memória da imagem
     * @return resource
     */
        public function getResource(){
                return $this->resource;
        }

        /**
     * Destrutor: libera a memória utilizada pela imagem
     */
        public function __destruct(){
                if($this->resource !== null)
                        imagedestroy($this->resource);
        }
}


ImageDecorator
/*
 * Adiciona elementos a uma imagem
 */
class ImageDecorator {
        /**
     * @property ImageAllocator $allocator : contém um objeto ImageAllocator que representa a imagem na memória princpal
     */
        private $allocator;
        
        /**
     * Contrutor
     * @param ImageAllocator $alloc
     */
        public function __construct(ImageAllocator $alloc){
                $this->allocator = $alloc;
        }
        
        /**
     * Desenha um caractere na imagem
     * @param char $char : o caractere a ser inserido
     * @param Point $start : a posição onde se encontrará o topo esquerdo do caractere
     * @param RGBColor $color : a cor do caractere
     * @param int $font : o tamanho da fonte [argumento padrão da função imagechar, pode assumir valores de 1 a 5]
     * @return ImageDecorator
     */
        public function drawChar($char, Point $start, RGBColor $color, $font = 1){
                imagechar($this->allocator->getResource(), $font, $start->getX(), $start->getY(), $char, $color->toHex());
                return $this;
        }
        
        /**
     * Desenha um caractere na vertical na imagem
     * @params idêntico ao método anterior
     * @return ImageDecorator 
     */
        public function drawCharUp($char, Point $start, RGBColor $color, $font = 1){
                imagecharup($this->allocator->getResource(), $font, $start->getX(), $start->getY(), $char, $color->toHex());
                return $this;
        }
        
        /**
     * Desenha um arco de elipse na imagem
     * @param Point $center : ponto que representa a posição da imagem que conterá o centro da elipse geradora do arco
     * @param int $wdt : largura da elipse
     * @param int $hgt : altura da elipse
     * @param int $start : ângulo de início do arco [0 corresponde à posicão 3 horas]
     * @param int $end : ângulo de fim do arco
     * @param RGBColor $color : cor do arco
     * @return ImageDecorator
     */
        public function drawArc(Point $center, $wdt, $hgt, $start, $end, RGBColor $color){
                imagearc($this->allocator->getResource(), $center->getX(), $center->getY(), (int) $wdt, (int)$hgt, (int) $start, (int) $end, $color->toHex());
                return $this;
        }
        
        /**
     * Desenha um arco de elipse preenchido     
     * @param Point $center : o centro da elipse base
     * @param int $wdt : a largura da elipse base
     * @param int $hgt : a altura da elipse base
     * @param int $start : o ângulo inicial [0 corresponde à posicão 3 horas]
     * @param int $end : o ângulo final
     * @param iRGBColor $color : a cor do arco
     * @param int $style : o estilo da elipse [visite http://www.php.net/m...gefilledarc.php para detalhes]
     * @return ImageDecorator
     */
        public function drawFilledArc(Point $center, $wdt, $hgt, $start, $end, RGBColor $color, $style = IMG_ARC_PIE){
                imagefilledarc($this->allocator->getResource(), $center->getX(), $center->getY(), (int) $wdt, (int)$hgt, (int) $start, (int) $end, $color->toHex(), $style);
                return $this;
        }
        
        /**
     * Desenha uma elipse na imagem
     * @param Point $center : o centro da elipse
     * @param int $wdt : a largura da elipse
     * @param int $hgt : a altura da elipse
     * @param RGBColor $color : a cor da elipse
     * @return ImageDecorator
     */
        public function drawElipse(Point $center, $wdt, $hgt, RGBColor $color){
                imageellipse($this->allocator->getResource(), $center->getX(), $center->getY(), (int) $wdt, (int) $hgt, $color->toHex());
                return $this;
        }
        
        /**
     * Desenha uma elipse preenchida
     * @param Point $center
     * @param $wdt
     * @param $hgt
     * @param RGBColor $color
     * @return ImageDecorator
     */
        public function drawFilledElipse(Point $center, $wdt, $hgt, RGBColor $color){
                imagefilledellipse($this->allocator->getResource(), $center->getX(), $center->getY(), (int) $wdt, (int) $hgt, $color->toHex());
                return $this;
        }
        
        /**
     * Desenha uma linha reta
     * @param Point $start : o início da linha
     * @param Point $end : o fim da linha
     * @param RGBColor $color : a cor da linha
     * @return ImageDecorator
     */
        public function drawLine(Point $start, Point $end, RGBColor $color){
                imageline($this->allocator->getResource(), $start->getX(), $start->getY(), $end->getX(), $end->getY(), $color->toHex());
                return $this;
        }
        
        /**
     * Desenha um retângulo
     * @param Point $start : o ponto inicial do retângulo
     * @param Point $end : o ponto final do retângulo
     * @param RGBColor $color : a cor do retangulo
     * @return ImageDecorator
     */
        public function drawRectangle(Point $start, Point $end, RGBColor $color){
                imagerectangle($this->allocator->getResource(), $start->getX(), $start->getY(), $end->getX(), $end->getY(), $color->toHex());
                return $this;
        }
        
        /**
     * Desenha um retângulo preenchido
     * @param Point $start
     * @param Point $end
     * @param RGBColor $color
     * @return ImageDecorator
     */
        public function drawFilledRectangle(Point $start, Point $end, RGBColor $color){
                imagefilledrectangle($this->allocator->getResource(), $start->getX(), $start->getY(), $end->getX(), $end->getY(), $color->toHex());
                return $this;
        }
        
        /**
     * Desenha uma string
     * @param string $str : a string a ser inserida
     * @param Point $start : o ponto inicial da string [referencial: topo esquerdo]
     * @param RGBColor $color : a cor do texto
     * @param int $font : o tamanho da fonte [argumento padrão da função imagechar, pode assumir valores de 1 a 5]
     * @return ImageDecorator
     */
        public function drawString($str, Point $start, RGBColor $color, $font = 5){
                imagestring($this->allocator->getResource(), $font, $start->getX(), $start->getY(), $str, $color->toHex());
                return $this;
        }
        
        /**
     * Desenha uma string na vertical
     * @param string $str
     * @param Point $start
     * @param RGBColor $color
     * @param int $font
     * @return ImageDecorator
     */
        public function drawStringUp($str, Point $start, RGBColor $color, $font = 5){
                imagestringup($this->allocator->getResource(), $font, $start->getX(), $start->getY(), $str, $color->toHex());
                return $this;
        }
        
        /**
     * Desenha um polígono
     * @param $points : vetor de objetos Point representando os vértices do polígono
     * @param RGBColor $color : a cor do polígono
     * @return ImageDecorator
     */
        public function drawPolygon(array $points, RGBColor $color){
                $pts = $this->pointsToArray($points);
                imagepolygon($this->allocator->getResource(), $pts, count($pts)/2, $color->toHex());
                return $this;
        }
        
        /**
     * Desenha um polígono preenchido
     * @param array $points
     * @param RGBColor $color
     * @return ImageDecorator
     */
        public function drawFilledPolygon(array $points, RGBColor $color){
                $pts = $this->pointsToArray($points);
                imagefilledpolygon($this->allocator->getResource(), $pts, count($pts)/2, $color->toHex());
                return $this;
        }
        
        /**
     * Converte um vetor de pontos para o formato exigido pelas funções imagepolygon e imagefilledpolygon
     * @param array $points : o vetor de pontos
     * @return array
     */
        private function pointsToArray(array $points){
                $pts = array();
                foreach($points as $key=>$each){
                        if($each instanceof Point){
                                $pts[] = $each->getX();
                                $pts[] = $each->getY();
                        } else if(is_array($each)){
                                $pts[] = $each[0];
                                $pts[] = $each[1];
                        } else {
                                throw new Exception('Ponto inválido ao desenhar o polígono!');
                        }
                }
                if(count($pts) < 3)
                        throw new Exception('Número insuficiente de pontos para desenha um polígono!');
                return $pts;
        }
        
        /**
     * Desenha um texto na tela utilizando a fonte carregada a partir do parâmetro $file
     * @param string $str : a string a ser escrita na imagem
     * @param int $size : o tamanho da fonte [em pt]
     * @param Point $start : o ponto inicial para a escrita [referêncial: topo esquerdo]
     * @param RGBColor $color : a cor do texto
     * @param string $file : o caminho para o arquivo *.ttf da fonte para a escrita
     * @param float $angle : a inclinação do texto [o giro é feito no sentido anti-horário]
     * @return ImageDecorator
     */
        public function drawTTFText($str, $size, Point $start, RGBColor $color, $file, $angle = 0){
                imagettftext ( $this->allocator->getResource(), $size, $angle, $start->getX(), $start->getY(), $color->toHex(), $file, $str);
                return $this;
        }

        /**
     * Preenche a imagem com a cor $color
     * @param RBGColor $color
     * @param Point $point : ponto inicial para o preenchimento
     * @return ImageDecorator
     */
        public function fill(RGBColor $color, Point $point){
                imagefill($this->allocator->getResource(), $point->getX(), $point->getY(), $color->toHex());
                return $this;
        }
        
        /**
     * Aplica um filtro à imagem
     * @param $filter : para mais detalhes, visite http://www.php.net/m...imagefilter.php
     * @return ImageDecorator
     */
        public function filter($filter, $_ = null){
                $args = array();
                $args[0] = $this->allocator->getResource();
                $args = array_merge($args, func_get_args());
                call_user_func_array('imagefilter', $args);
                return $this;
        }
        
        /**
     * Preenche um único pixel com a cor $color
     * @param Point $pt : pixel a ser preenchido
     * @param RGBColor $color
     * @return ImageDecorator
     */
        public function setPixel(Point $pt, RGBColor $color){
                imagesetpixel($this->allocator->getResource(), $pt->getX(), $pt->getY(), $color->toHex());
                return $this;
        }
}


ImageHandler
<?php<?php/*
 * Realiza as operações mais comuns em uma imagem
 */
class ImageHandler {
        const IMAGE_RESIZE_FORCED = true;
        const IMAGE_RESIZE_NOT_FORCED = false;

        const IMAGE_QUALITY_MAX = 100;
        const IMAGE_QUALITY_HIGH = 90;
        const IMAGE_QUALITY_MEDIUM = 75;
        const IMAGE_QUALITY_COMPACT = 50;

        /**
         * Redimensiona a imagem atual
         * @param ImageAllocator $src : a imagem para ser redimensionada
         * @param int $new_wdt : nova largura
         * @param int $new_hgt : nova altura
         * @param bool $forced : true  -> a imagem redimensionada terá exatamente as dimensões informadas
         *                                               false -> a imagem será redimensionada proporcionalmente
         * @param int $quality : qualidade da imagem
         * @return ImageAllocator
         */
        public function resize(ImageAllocator $src, $new_wdt, $new_hgt, $forced = self::IMAGE_RESIZE_NOT_FORCED, $quality = self::IMAGE_QUALITY_MAX){
                if($forced === false){
                        $ratio = self::getRatio($src, $new_wdt, $new_hgt);
                        $new_wdt = round($src->getWidth() * $ratio);
                        $new_hgt = round($src->getHeight() * $ratio);
                }

                $dst = new ImageAllocator($new_wdt, $new_hgt);

                imagecopyresampled($dst->getResource(), $src->getResource(), 0, 0, 0, 0, $new_wdt, $new_hgt, $src->getWidth(), $src->getHeight());
                return $dst;
        }

        /**
         * Mescla duas imagens, aplicando $sr em $dst
         * @param ImageAllocator $src : recurso de imagem de origem
         * @param ImageAllocator $dst : recurso de imagem de destino
         * @param Point $dst_pt : ponto a partir do qual a imagem será mesclada [referencial: topo esquerdo]
         * @param $src_wdt : a largura da imagem mesclada
         * @param $src_hgt : a altura da imagem mesclada
         * @param $pct : a opacidade da imagem mesclada
         * @return ImageAllocator
         */
        public function merge(ImageAllocator $src, ImageAllocator $dst, Point $dst_pt, $src_wdt, $src_hgt, $opct = 10){
                $tmp = $this->resize($src, $src_wdt, $src_hgt, true);
                imagecopymerge($dst->getResource(), $tmp->getResource(), $dst_pt->getX(), $dst_pt->getY(), 0, 0, $src_wdt, $src_hgt, $opct);

                return $dst;
        }

        /**
         * Corta a imagem $src_img a partir do ponto $referencial
         * @param ImageAllocator $src : o recurso da imagem a ser cortada
         * @param int $new_wdt : a largura do corte
         * @param int $new_hgt : a altura do corte
         * @param Point $referencial : referencial para o corte
         * @param Point $margin : ponto à partir do qual uma margem é criada.
         *                                                      Vertical [coord. y]: (+) -> margem acima
         *                                                                                               (-) -> margem abaixo
         *                                                      Horizontal [coord. x]: (+) -> margem esquerda
         *                                                                                                 (-) -> margem direita
         * @param bool $forced : true  -> força o corte a ter as dimensões informadas
         *                                               false -> corta a imagem proporcionalmente
         * @param bool $prev_neg : previne que o corte comece fora dos limites da imagem
         * @return ImageAllocator
         */
        public function crop(ImageAllocator $src, $new_wdt, $new_hgt, Point $referencial = null, Point $margin = null, $forced = true, $prev_neg = true){
                if($forced === false){
                        $ratio = self::getRatio($src, $new_wdt, $new_hgt);
                        $new_wdt = round($src->getWidth() * $ratio);
                        $new_hgt = round($src->getHeight() * $ratio);
                }

                if($referencial === null){
                        $tlx = floor($src->getWidth() / 2) - floor($new_wdt / 2);
                        $tly = floor($src->getHeight() / 2) - floor($new_hgt / 2);
                        $referencial = new Point($tlx, $tly);
                }

                if($margin === null)
                        $margin = new Point(0, 0);

                if($prev_neg === true){
                        /* Impedir que o corte comece antes do canto superior esquerdo */
                        if ($referencial->getX() < 0)
                                $referencial->setX(0);

                        if ($referencial->getY() < 0)
                                $referencial->setY(0);
                        /* / */

                        /* Impedir que o corte comece depois do canto inferior direito */
                        if ($referencial->getX() > $src->getWidth())
                                $referencial->setX($src->getWidth() - $new_wdt);

                        if ($referencial->getY() > $src->getHeight())
                                $referencial->setY($src->getHeight() - $new_hgt);
                        /* / */
                }

                $dst = new ImageAllocator($new_wdt, $new_hgt);

                imagecopy($dst->getResource(), $src->getResource(), $margin->getX(), $margin->getY(), $referencial->getX(), $referencial->getY(), $new_wdt, $new_hgt);
                return $dst;
        }

        /**
         * Retorna a proporção de redimensionamento de uma imagem
         * @param ImageAllocator $src : recurso de imagem
         * @param $new_wdt : largura desejada
         * @param $new_hgt : altura desejada
         * @return float
         */
        public static function getRatio(ImageAllocator $src, $new_wdt, $new_hgt){
                return min($new_wdt/$src->getWidth(), $new_hgt/$src->getHeight());
        }
}


Utilização:
//Criando um thumbnail
$handler = new ImageHandler();
$src = new Image('imagem.jpg');
$aloc = $handler->resize($src, 200, 160);
$aloc->output('thumb.jpg', 80);

Lembrando que o tipo da imagem salva é definida automaticamente pela extensão, não precisando informá-lo

Essa é só a base para impelentações em níveis maiores.
Por exemplo, criando uma função para criar thumbnails a partir de uma imagem:

function generateThumb($original_path, $thumb_path, $w, $h, $quality = 100, $force_redim = false){
        $handler = new ImageHandler();
        $src = new Image($original_path);
        $aloc = $handler->resize($src, $w, $h, $force_redim, $quality);
        $aloc->output($thumb_path, $quality);
}


Para utilizar:
generateThumb('imagem.jpg', 'thumb.jpg', 200, 160);

0 comentários:

Postar um comentário

Share

Twitter Delicious Facebook Digg Stumbleupon Favorites More