Вход Регистрация
Файл: protected/extensions/CImageHandler/CImageHandler.php
Строк: 340
<?php
/**
 * Image handler
 * @author Yaroslav Pelesh aka Tokolist http://tokolist.com
 * @link https://github.com/tokolist/yii-components
 * @version 1.2
 * @license http://www.opensource.org/licenses/mit-license.php The MIT License
 */

class CImageHandler extends CApplicationComponent
{
    private 
$originalImage = null;
    private 
$image = null;

    private 
$format = 0;

    private 
$width = 0;
    private 
$height = 0;

    private 
$mimeType = '';

    private 
$fileName = '';

    public 
$transparencyColor = array(0, 0, 0);


    const 
IMG_GIF = 1;
    const 
IMG_JPEG = 2;
    const 
IMG_PNG = 3;

    const 
CORNER_LEFT_TOP = 1;
    const 
CORNER_RIGHT_TOP = 2;
    const 
CORNER_LEFT_BOTTOM = 3;
    const 
CORNER_RIGHT_BOTTOM = 4;
    const 
CORNER_CENTER = 5;


    const 
FLIP_HORIZONTAL = 1;
    const 
FLIP_VERTICAL = 2;
    const 
FLIP_BOTH = 3;


    public function 
getImage()
    {
        return 
$this->image;
    }

    public function 
getFormat()
    {
        return 
$this->format;
    }

    public function 
getWidth()
    {
        return 
$this->width;
    }

    public function 
getHeight()
    {
        return 
$this->height;
    }

    public function 
getMimeType()
    {
        return 
$this->mimeType;
    }

    public function 
__destruct()
    {
        
$this->freeImage();
    }

    private function 
freeImage()
    {
        if(
is_resource($this->image))
        {
            
imagedestroy($this->image);
        }
        
        if(
$this->originalImage !== null)
        {
            if(
is_resource($this->originalImage['image']))
            {
                
imagedestroy($this->originalImage['image']);
            }
            
$this->originalImage = null;
        }
    }

    private function 
checkLoaded()
    {
        if (!
is_resource($this->image))
        {
            throw new 
Exception('Load image first');
        }
    }

    private function 
loadImage($file)
    {
        
$result = array();



        if (
$imageInfo = @getimagesize($file))
        {
            
$result['width'] = $imageInfo[0];
            
$result['height'] = $imageInfo[1];

            
$result['mimeType'] = $imageInfo['mime'];

            switch (
$result['format'] = $imageInfo[2])
            {
                case 
self::IMG_GIF:
                    if (
$result['image'] = imagecreatefromgif($file))
                    {
                        return 
$result;
                    }
                    else
                    {
                        throw new 
Exception('Invalid image gif format');
                    }
                    break;
                case 
self::IMG_JPEG:
                    if (
$result['image'] = imagecreatefromjpeg($file))
                    {
                        return 
$result;
                    }
                    else
                    {
                        throw new 
Exception('Invalid image jpeg format');
                    }
                    break;
                case 
self::IMG_PNG:
                    if (
$result['image'] = imagecreatefrompng($file))
                    {
                        return 
$result;
                    }
                    else
                    {
                        throw new 
Exception('Invalid image png format');
                    }
                    break;
                  default:
                      throw new 
Exception('Not supported image format');
              }
          }
          else
          {
              throw new 
Exception('Invalid image file');
          }


    }
    
    protected function 
initImage($image = false)
    {
        if(
$image === false)
        {
            
$image = $this->originalImage;
        }
        
        
$this->width = $image['width'];
        
$this->height = $image['height'];
        
$this->mimeType = $image['mimeType'];
        
$this->format = $image['format'];
        
        
//Image
        
if(is_resource($this->image))
            
imagedestroy($this->image);
        
        
$this->image = imagecreatetruecolor($this->width, $this->height);
        
$this->preserveTransparency($this->image);
        
imagecopy($this->image, $image['image'], 0, 0, 0, 0, $this->width, $this->height);
    }

    public function 
load($file)
    {
        
$this->freeImage();

        if((
$this->originalImage = $this->loadImage($file)))
        {
            
$this->initImage();
            
$this->fileName = $file;


            return 
$this;
        }
        else
        {
            return 
false;
        }
    }

    public function 
reload()
    {
        
$this->checkLoaded();
        
$this->initImage();

        return 
$this;
    }

    private function 
preserveTransparency($newImage)
    {
        switch(
$this->format)
        {
            case 
self::IMG_GIF:
                
$color = imagecolorallocate(
                    
$newImage,
                    
$this->transparencyColor[0],
                    
$this->transparencyColor[1],
                    
$this->transparencyColor[2]
                );

                
imagecolortransparent($newImage, $color);
                
imagetruecolortopalette($newImage, false, 256);
                break;
            case 
self::IMG_PNG:
                
imagealphablending($newImage, false);

                
$color = imagecolorallocatealpha (
                    
$newImage,
                    
$this->transparencyColor[0],
                    
$this->transparencyColor[1],
                    
$this->transparencyColor[2],
                    
0
                
);
                
                
imagefill($newImage, 0, 0, $color);
                
imagesavealpha($newImage, true);
                break;
        }
    }

    public function 
resize($toWidth, $toHeight, $proportional = true)
    {
        
$this->checkLoaded();
        
        
$toWidth = $toWidth !== false ? $toWidth : $this->width;
        
$toHeight = $toHeight !== false ? $toHeight : $this->height;

        if(
$proportional)
        {
            
$newHeight = $toHeight;
            
$newWidth = round($newHeight / $this->height * $this->width);
            
            
            if(
$newWidth > $toWidth)
            {
                
$newWidth = $toWidth;
                
$newHeight = round($newWidth / $this->width * $this->height);
            }
        }
        else
        {
            
$newWidth = $toWidth;
            
$newHeight = $toHeight;
        }

        
$newImage = imagecreatetruecolor($newWidth, $newHeight);

        
$this->preserveTransparency($newImage);

        
imagecopyresampled($newImage, $this->image, 0, 0, 0, 0, $newWidth, $newHeight, $this->width, $this->height);



        
imagedestroy($this->image);

        
$this->image = $newImage;
        
$this->width = $newWidth;
        
$this->height = $newHeight;

        return 
$this;

    }

    public function 
thumb($toWidth, $toHeight, $proportional = true)
    {
        
$this->checkLoaded();

        if(
$toWidth !== false)
            
$toWidth = min($toWidth, $this->width);
        
        if(
$toHeight !== false)
            
$toHeight = min($toHeight, $this->height);


        
$this->resize($toWidth, $toHeight, $proportional);

        return 
$this;

    }

    public function 
watermark($watermarkFile, $offsetX, $offsetY, $corner = self::CORNER_RIGHT_BOTTOM, $zoom = false)
    {

        
$this->checkLoaded();

        if (
$wImg = $this->loadImage($watermarkFile))
        {

            
$posX = 0;
            
$posY = 0;
                        
            
$watermarkWidth = $wImg['width'];
            
$watermarkHeight = $wImg['height'];

            if(
$zoom !== false)
            {
                
$dimension = round(max($this->width, $this->height) * $zoom);

                
$watermarkHeight = $dimension;
                
$watermarkWidth = round($watermarkHeight / $wImg['height'] * $wImg['width']);

                if(
$watermarkWidth > $dimension)
                {
                    
$watermarkWidth = $dimension;
                    
$watermarkHeight = round($watermarkWidth / $wImg['width'] * $wImg['height']);
                }
            }

            switch (
$corner)
            {
                case 
self::CORNER_LEFT_TOP:
                    
$posX = $offsetX;
                    
$posY = $offsetY;
                    break;
                case 
self::CORNER_RIGHT_TOP:
                    
$posX = $this->width - $watermarkWidth - $offsetX;
                    
$posY = $offsetY;
                    break;
                case 
self::CORNER_LEFT_BOTTOM:
                    
$posX = $offsetX;
                    
$posY = $this->height - $watermarkHeight - $offsetY;
                    break;
                case 
self::CORNER_RIGHT_BOTTOM:
                    
$posX = $this->width - $watermarkWidth - $offsetX;
                    
$posY = $this->height - $watermarkHeight - $offsetY;
                    break;
                case 
self::CORNER_CENTER:
                    
$posX = floor(($this->width - $watermarkWidth) / 2);
                    
$posY = floor(($this->height - $watermarkHeight) / 2);
                    break;
                default:
                    throw new 
Exception('Invalid $corner value');
            }

            
imagecopyresampled(
                
$this->image,
                
$wImg['image'],
                
$posX,
                
$posY,
                
0,
                
0,
                
$watermarkWidth,
                
$watermarkHeight,
                
$wImg['width'],
                
$wImg['height']
            );


            
imagedestroy($wImg['image']);

            return 
$this;
        }
        else
        {
            return 
false;
        }
    }


    public function 
flip($mode)
    {
        
$this->checkLoaded();

        
$srcX = 0;
        
$srcY = 0;
        
$srcWidth = $this->width;
        
$srcHeight = $this->height;

        switch (
$mode)
        {
            case 
self::FLIP_HORIZONTAL:
                
$srcX = $this->width - 1;
                
$srcWidth = -$this->width;
                break;
            case 
self::FLIP_VERTICAL:
                
$srcY = $this->height - 1;
                
$srcHeight = -$this->height;
                break;
            case 
self::FLIP_BOTH:
                
$srcX = $this->width - 1;
                
$srcY = $this->height - 1;
                
$srcWidth = -$this->width;
                
$srcHeight = -$this->height;
                break;
            default:
                throw new 
Exception('Invalid $mode value');
        }

        
$newImage = imagecreatetruecolor($this->width, $this->height);
        
$this->preserveTransparency($newImage);

        
imagecopyresampled($newImage, $this->image, 0, 0, $srcX, $srcY, $this->width, $this->height, $srcWidth, $srcHeight);

        
imagedestroy($this->image);

        
$this->image = $newImage;
        
//dimensions not changed

        
return $this;
    }

    public function 
rotate($degrees)
    {
        
$this->checkLoaded();

        
$degrees = (int) $degrees;
        
$this->image = imagerotate($this->image, $degrees, 0);

        
$this->width = imagesx($this->image);
        
$this->height = imagesy($this->image);

        return 
$this;
    }

    public function 
crop($width, $height, $startX = false, $startY = false)
    {
        
$this->checkLoaded();

        
$width = (int) $width;
        
$height = (int) $height;

        
//Centered crop
         
$startX = $startX === false ? floor(($this->width - $width) / 2) : intval($startX);
        
$startY = $startY === false ? floor(($this->height - $height) / 2) : intval($startY);

        
//Check dimensions
        
$startX = max(0, min($this->width, $startX));
        
$startY = max(0, min($this->height, $startY));
        
$width = min($width, $this->width - $startX);
        
$height = min($height, $this->height - $startY);


        
$newImage = imagecreatetruecolor($width, $height);

        
$this->preserveTransparency($newImage);

        
imagecopyresampled($newImage, $this->image, 0, 0, $startX, $startY, $width, $height, $width, $height);

        
imagedestroy($this->image);

        
$this->image = $newImage;
        
$this->width = $width;
        
$this->height = $height;

        return 
$this;
    }

    public function 
text($text, $fontFile, $size=12, $color=array(0, 0, 0),
        
$corner=self::CORNER_LEFT_TOP, $offsetX=0, $offsetY=0, $angle=0)
    {
        
$this->checkLoaded();

        
$bBox = imagettfbbox($size, $angle, $fontFile, $text);
        
$textHeight = $bBox[1] - $bBox[7];
        
$textWidth = $bBox[2] - $bBox[0];

        
$color = imagecolorallocate($this->image, $color[0], $color[1], $color[2]);



        switch (
$corner)
        {
            case 
self::CORNER_LEFT_TOP:
                
$posX = $offsetX;
                
$posY = $offsetY;
                break;
            case 
self::CORNER_RIGHT_TOP:
                
$posX = $this->width - $textWidth - $offsetX;
                
$posY = $offsetY;
                break;
            case 
self::CORNER_LEFT_BOTTOM:
                
$posX = $offsetX;
                
$posY = $this->height - $textHeight - $offsetY;
                break;
            case 
self::CORNER_RIGHT_BOTTOM:
                
$posX = $this->width - $textWidth - $offsetX;
                
$posY = $this->height - $textHeight - $offsetY;
                break;
            case 
self::CORNER_CENTER:
                
$posX = floor(($this->width - $textWidth) / 2);
                
$posY = floor(($this->height - $textHeight) / 2);
                break;
            default:
                throw new 
Exception('Invalid $corner value');
        }



        
imagettftext($this->image, $size, $angle, $posX, $posY + $textHeight, $color, $fontFile, $text);

        return 
$this;
    }

    public function 
adaptiveThumb($width, $height)
    {
        
$this->checkLoaded();

        
$width = intval($width);
        
$height = intval($height);

        
$widthProportion = $width / $this->width;
        
$heightProportion = $height / $this->height;

        if (
$widthProportion > $heightProportion)
        {
            
$newWidth = $width;
            
$newHeight = round($newWidth / $this->width * $this->height);
        }
        else
        {
            
$newHeight = $height;
            
$newWidth = round($newHeight / $this->height * $this->width);
        }

        
$this->resize($newWidth, $newHeight);

        
$this->crop($width, $height);

        return 
$this;
    }

    public function 
resizeCanvas($toWidth, $toHeight, $backgroundColor = array(255, 255, 255))
    {
        
$this->checkLoaded();

        
$newWidth = min($toWidth, $this->width);
        
$newHeight = min($toHeight, $this->height);

        
$widthProportion = $newWidth / $this->width;
        
$heightProportion = $newHeight / $this->height;

        if(
$widthProportion < $heightProportion)
        {
            
$newHeight = round($widthProportion * $this->height);
        }
        else
        {
            
$newWidth = round($heightProportion * $this->width);
        }

        
$posX = floor(($toWidth - $newWidth) / 2);
        
$posY = floor(($toHeight - $newHeight) / 2);


        
$newImage = imagecreatetruecolor($toWidth, $toHeight);

        
$backgroundColor = imagecolorallocate($newImage, $backgroundColor[0], $backgroundColor[1], $backgroundColor[2]);
        
imagefill($newImage, 0, 0, $backgroundColor);

        
imagecopyresampled($newImage, $this->image, $posX, $posY, 0, 0, $newWidth, $newHeight, $this->width, $this->height);

        
imagedestroy($this->image);

        
$this->image = $newImage;
        
$this->width = $toWidth;
        
$this->height = $toHeight;

        return 
$this;
    }
    
    public function 
grayscale()
    {
        
$newImage = imagecreatetruecolor($this->width, $this->height);

        
imagecopy($newImage, $this->image, 0, 0, 0, 0, $this->width, $this->height);
        
imagecopymergegray($newImage, $newImage, 0, 0, 0, 0, $this->width, $this->height, 0);

        
imagedestroy($this->image);
        
        
$this->image = $newImage;
        
        return 
$this;
    }

    public function 
show($inFormat = false, $jpegQuality = 75)
    {
        
$this->checkLoaded();

        if (!
$inFormat)
        {
            
$inFormat = $this->format;
        }

        switch (
$inFormat)
        {
            case 
self::IMG_GIF:
                
header('Content-type: image/gif');
                
imagegif($this->image);
                break;
            case 
self::IMG_JPEG:
                
header('Content-type: image/jpeg');
                
imagejpeg($this->image, null, $jpegQuality);
                break;
            case 
self::IMG_PNG:
                
header('Content-type: image/png');
                
imagepng($this->image);
                break;
            default:
                throw new 
Exception('Invalid image format for putput');
        }

        return 
$this;
    }

    public function 
save($file = false, $toFormat = false, $jpegQuality = 75, $touch = false)
    {
        if (empty(
$file))
        {
            
$file = $this->fileName;
        }

        
$this->checkLoaded();

        if (!
$toFormat)
        {
            
$toFormat = $this->format;
        }

        switch (
$toFormat)
        {
            case 
self::IMG_GIF:
                if (!
imagegif($this->image, $file))
                {
                    throw new 
Exception('Can't save gif file');
                }
                break;
            case self::IMG_JPEG:
                if (!imagejpeg($this->image, $file, $jpegQuality))
                {
                    throw new Exception('
Can't save jpeg file');
                }
                break;
            case 
self::IMG_PNG:
                if (!
imagepng($this->image, $file))
                {
                    throw new 
Exception('Can't save png file');
                }
                break;
            default:
                throw new Exception('
Invalid image format for save');
        }

        if ($touch && $file != $this->fileName)
        {
            touch($file, filemtime($this->fileName));
        }

        return $this;
    }

}
Онлайн: 1
Реклама