Вход Регистрация
Файл: oc-includes/osclass/classes/ImageResizer.php
Строк: 240
<?php if ( ! defined('ABS_PATH')) exit('ABS_PATH is not loaded. Direct access is not allowed.');
/*
 * Copyright 2014 Osclass
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

    /**
     * This class represents a utility to load and resize images easily.
     */
    
class ImageResizer {

        public static function 
fromFile($imagePath) {
            return new 
ImageResizer($imagePath);
        }

        private 
$im;
        private 
$image_info;
        private 
$ext;
        private 
$mime;

        private 
$_font;
        private 
$_color;
        private 
$_width;
        private 
$_height;
        private 
$_exif;
        private 
$_watermarked false;


        private function 
__construct($imagePath) {
            if(!
file_exists($imagePath)) { throw new Exception(sprintf(__("%s does not exist!"), $imagePath)); };
            if(!
is_readable($imagePath)) { throw new Exception(sprintf(__("%s is not readable!"), $imagePath)); };
            if(
filesize($imagePath)==0) { throw new Exception(sprintf(__("%s is corrupt or broken!"), $imagePath)); };

            
$this->image_info = @getimagesize($imagePath);
            if(
osc_use_imagick()) {
                
$this->im = new Imagick($imagePath);
                
$geometry $this->im->getImageGeometry();
                
$this->_width $geometry['width'];
                
$this->_height $geometry['height'];
            } else {
                
$content file_get_contents($imagePath);
                
$this->im imagecreatefromstring($content);
                
$this->_width imagesx($this->im);
                
$this->_height imagesy($this->im);

                
$this->_exif = array();
                if(@
$this->image_info['mime']=='image/jpeg' && function_exists('exif_read_data')) {
                    
$this->_exif exif_read_data($imagePath);
                }

            }

            switch (@
$this->image_info['mime']) {
                case 
'image/gif':
                case 
'image/png':
                    
$this->ext 'png';
                    
$this->mime 'image/png';
                    break;
                default:
                    
$this->ext 'jpg';
                    
$this->mime 'image/jpeg';
                    if(!
osc_use_imagick()) {
                        
$bg imagecreatetruecolor($this->_width$this->_height);
                        
imagefill($bg00imagecolorallocatealpha($bg255255255127));
                        
imagesavealpha($bgtrue);
                        
imagealphablending($bgTRUE);
                        
imagecopy($bg$this->im0000$this->_width$this->_height);
                        
imagedestroy($this->im);
                        
$this->im $bg;
                    }
                    break;
            }

            return 
$this;
        }

        public function 
__destruct() {
            if(
osc_use_imagick()) {
                
$this->im->destroy();
            } else {
                
imagedestroy($this->im);
            }
        }

        public function 
getExt() { return $this->ext; }
        public function 
getMime() { return $this->mime; }

        public function 
resizeTo($width$height$force_aspect null$upscale true) {
            if(
$force_aspect==null) {
                
$force_aspect osc_force_aspect_image();
            }

            if((
$this->_width/$this->_height)>=($width/$height)) {
                if(
$upscale) { $newW $width; } else { $newW = ($this->_width$width)? $width $this->_width; };
                
$newH ceil($this->_height * ($newW $this->_width));
                if(
$force_aspect) { $height $newH; }
            } else {
                if(
$upscale) { $newH $height; } else { $newH = ($this->_height $height)? $height $this->_height; };
                
$newW ceil($this->_width* ($newH $this->_height));
                if(
$force_aspect) { $width $newW; }
            }

            if(
osc_use_imagick()) {
                
$bg = new Imagick();
                if(
$this->ext=='jpg') {
                    
$bg->newImage($width$height'white');
                } else {
                    
$bg->newImage($width$height'none');
                }
                
$this->im->thumbnailImage($width$heighttrue);
                
$bg->compositeImage$this->imimagick::COMPOSITE_OVERfloor(($width-$newW)/2), floor(($height-$newH)/2));
                
$this->im $bg;
            } else {
                
$newIm imagecreatetruecolor($width,$height);
                
imagealphablending($newImfalse);
                
$colorTransparent imagecolorallocatealpha($newIm255255255127);
                
imagefill($newIm00$colorTransparent);
                
imagesavealpha($newImtrue);
                
imagecopyresampled($newIm$this->imfloor(($width-$newW)/2), floor(($height-$newH)/2), 00$newW$newH$this->_width$this->_height);
                
imagedestroy($this->im);
                
$this->im $newIm;
            }
            
$this->_width $width;
            
$this->_height $height;
            return 
$this;
        }

        public function 
saveToFile($imagePath$ext null) {
            if(
file_exists($imagePath) && !is_writable($imagePath)) { throw new Exception("$imagePath is not writable!"); };
            if(
$ext==null) { $ext $this->ext; };
            if(
$ext!='png' && $ext!='gif') { $ext 'jpeg'; };
            if(
osc_use_imagick()) {
                if(
$ext=='jpeg' && ($this->ext!='jpeg' && $this->ext!='jpg')) {
                    
$bg = new Imagick();
                    
$bg->newImage($this->_width$this->_height'white');
                    
$this->im->thumbnailImage($this->_width$this->_heighttrue);
                    
$bg->compositeImage$this->imimagick::COMPOSITE_OVER00);
                    
$this->im $bg;
                    
$this->ext 'jpeg';
                }
                
$this->im->setImageFileName($imagePath);
                
$this->im->setImageFormat($ext);
                
$this->im->writeImage($imagePath);
            } else {
                switch (
$ext) {
                    case 
'gif':
                    case 
'png':
                        
imagepng($this->im$imagePath0);
                        break;
                    default:
                        if((
$ext=='jpeg' && ($this->ext!='jpeg' && $this->ext!='jpg')) || $this->_watermarked) {
                            
$this->ext 'jpeg';
                        }
                        
imagejpeg($this->im$imagePath);
                        break;
                }
            }
        }

        public function 
autoRotate() {
            if(
osc_use_imagick()) {
                switch(
$this->im->getImageOrientation()) {
                    case 
imagick::ORIENTATION_TOPRIGHT:
                        
$this->im->flopImage();
                        break;

                    case 
imagick::ORIENTATION_BOTTOMRIGHT:
                        
$this->im->rotateimage(new ImagickPixel('none'), 180); // rotate 180 degrees
                        
break;

                    case 
imagick::ORIENTATION_BOTTOMLEFT:
                        
$this->im->flopImage();
                        
$this->im->rotateImage(new ImagickPixel('none'), 180);
                        break;

                    case 
imagick::ORIENTATION_LEFTTOP:
                        
$this->im->flopImage();
                        
$this->im->rotateImage(new ImagickPixel('none'), -90);
                        break;

                    case 
imagick::ORIENTATION_RIGHTTOP:
                        
$this->im->rotateimage(new ImagickPixel('none'), 90); // rotate 90 degrees CW
                        
break;

                    case 
imagick::ORIENTATION_RIGHTBOTTOM:
                        
$this->im->flopImage();
                        
$this->im->rotateImage(new ImagickPixel('none'), 90);
                        break;

                    case 
imagick::ORIENTATION_LEFTBOTTOM:
                        
$this->im->rotateimage(new ImagickPixel('none'), -90); // rotate 90 degrees CCW
                        
break;
                    default:
                        
// DO NOTHING, THE IMAGE IS OK OR WE DON'T KNOW IF IT'S ROTATED
                        
break;
                }
            } else {
                if(isset(
$this->_exif['Orientation'])) {
                    switch(
$this->_exif['Orientation']) {
                        case 
1:
                        default:
                            
// DO NOTHING, THE IMAGE IS OK OR WE DON'T KNOW IF IT'S ROTATED
                            
break;
                        case 
2:
                            
imageflip($this->imIMG_FLIP_HORIZONTAL);
                            break;
                        case 
3:
                            
$this->im imagerotate($this->im1800);
                            break;
                        case 
4:
                            
$this->im imagerotate($this->im1800);
                            
imageflip($this->imIMG_FLIP_HORIZONTAL);
                            break;
                        case 
5:
                            
$this->im imagerotate($this->im2700);
                            
imageflip($this->imIMG_FLIP_HORIZONTAL);
                            
$aux $this->_height;
                            
$this->_height $this->_width;
                            
$this->_width $aux;
                            break;
                        case 
6:
                            
$this->im imagerotate($this->im, -900);
                            
$aux $this->_height;
                            
$this->_height $this->_width;
                            
$this->_width $aux;
                            break;
                        case 
7:
                            
$this->im imagerotate($this->im900);
                            
imageflip($this->imIMG_FLIP_HORIZONTAL);
                            
$aux $this->_height;
                            
$this->_height $this->_width;
                            
$this->_width $aux;
                            break;
                        case 
8:
                            
$this->im imagerotate($this->im900);
                            
$aux $this->_height;
                            
$this->_height $this->_width;
                            
$this->_width $aux;
                            break;
                    }
                    
$this->_exif['Orientation'] = 1;

                }
            }
            return 
$this;
        }

        public function 
show() {
            
header('Content-Disposition: Attachment;filename=image.'.$this->ext);
            
header('Content-type: '.$this->mime);
            if(
osc_use_imagick()) {
            } else {
                switch (
$this->ext) {
                    case 
'gif':
                    case 
'png':
                        
imagepng($this->im);
                        break;
                    default:
                        
imagejpeg($this->im);
                        break;
                }
            }
        }

        public function 
doWatermarkText($text$color 'ff0000') {
            
$this->_watermarked true;
            
$this->_font osc_apply_filter('watermark_font_path'LIB_PATH "osclass/assets/fonts/Arial.ttf");
            if(
osc_use_imagick()) {
                
$draw = new ImagickDraw();
                
$draw->setFillColor("#".$color);
                
$draw->setFont($this->_font);
                
$draw->setFontSize30 );
                
$metrics $this->im->queryFontMetrics($draw$text);
                switch(
osc_watermark_place()) {
                    case 
'tl':
                        
$offset['x'] = 1;
                        
$offset['y'] = $metrics['ascender']+1;
                        break;
                    case 
'tr':
                        
$offset['x'] = $this->_width $metrics['textWidth']-1;
                        
$offset['y'] = $metrics['ascender']+1;
                        break;
                    case 
'bl':
                        
$offset['x'] = 1;
                        
$offset['y'] = $this->_height-1;
                        break;
                    case 
'br':
                        
$offset['x'] = $this->_width $metrics['textWidth']-1;
                        
$offset['y'] = $this->_height-1;
                        break;
                    default:
                        
$offset['x'] = ($this->_width 2) - ($metrics['textWidth'] / 2);
                        
$offset['y'] = ($this->_height 2) - ($metrics['ascender'] / 2);
                        break;
                }
                
$this->im->annotateImage($draw$offset['x'], $offset['y'], 0$text);
            } else {
                
imagealphablending$this->imtrue );
                
imagesavealpha$this->imtrue );
                if(
$this->ext!='jpg') {
                    
$white imagecolorallocatealpha($this->im255255255127);
                    
imagefill($this->im00$white);
                }
                
$color  $this->_imageColorAllocateHex($color);
                
$offset $this->_calculateOffset($text);
                
imagettftext($this->im200$offset['x'], $offset['y'], $color$this->_font html_entity_decode($textnull"UTF-8"));
            }
            return 
$this;
        }


        private function 
_imageColorAllocateHex($hexstr) {
            
$red    hexdec(substr($hexstr02));
            
$green  hexdec(substr($hexstr22));
            
$blue   hexdec(substr($hexstr42));


            return 
imagecolorallocate($this->im$red$green$blue);
        }

        private function 
_calculateOffset($text) {
            
$offset = array('x' => 0'y' => 0);
            
$bbox   $this->_calculateBBox($text);

            switch( 
osc_watermark_place() ) {
                case 
'tl':
                    
$offset['x'] = $bbox['height'];
                    
$offset['y'] = $bbox['height'] * 1.5;
                    break;
                case 
'tr':
                    
$offset['x'] = $this->_width - ($bbox['width'] + $bbox['height']);
                    
$offset['y'] = $bbox['height'] * 1.5;
                    break;
                case 
'bl':
                    
$offset['x'] = $bbox['height'];
                    
$offset['y'] = $this->_height $bbox['height'];
                    break;
                case 
'br':
                    
$offset['x'] = $this->_width - ($bbox['width'] + $bbox['height']);
                    
$offset['y'] = $this->_height $bbox['height'];
                    break;
                default:
                    
$offset['x'] = ($this->_width 2) - ($bbox['top_right']['x'] / 2);
                    
$offset['y'] = ($this->_height 2) - ($bbox['top_right']['y'] / 2);
                    break;
            }

            return 
$offset;
        }

        private function 
_calculateBBox($text) {
            
$bbox imagettfbbox(
                
20,
                
0,
                
$this->_font,
                
$text
            
);

            
$bbox = array(
                
'bottom_left'  => array(
                    
'x' => $bbox[0],
                    
'y' => $bbox[1]
                ),
                
'bottom_right' => array(
                    
'x' => $bbox[2],
                    
'y' => $bbox[3]
                ),
                
'top_right'    => array(
                    
'x' => $bbox[4],
                    
'y' => $bbox[5]
                ),
                
'top_left'     => array(
                    
'x' => $bbox[6],
                    
'y' => $bbox[7]
                )
            );

            
$bbox['width']  = $bbox['top_right']['x'] - $bbox['top_left']['x'];
            
$bbox['height'] = $bbox['bottom_left']['y'] - $bbox['top_left']['y'];

            return 
$bbox;
        }

        public function 
doWatermarkImage()
        {
            
$this->_watermarked true;
            
$path_watermark osc_uploads_path() . 'watermark.png';
            if(
osc_use_imagick()) {
                
$wm = new Imagick($path_watermark);
                
$wgeo $wm->getImageGeometry();

                switch(
osc_watermark_place()) {
                    case 
'tl':
                        
$dest_x 0;
                        
$dest_y 0;
                        break;
                    case 
'tr':
                        
$dest_x $this->_width $wgeo['width'];
                        
$dest_y 0;
                        break;
                    case 
'bl':
                        
$dest_x 0;
                        
$dest_y $this->_height $wgeo['height'];
                        break;
                    case 
'br':
                        
$dest_x $this->_width $wgeo['width'];
                        
$dest_y $this->_height $wgeo['height'];
                        break;
                    default:
                        
$dest_x = ($this->_width-$wgeo['width'])/2;
                        
$dest_y = ($this->_height-$wgeo['height'])/2;
                        break;
                }

                
$this->im->compositeImage$wmimagick::COMPOSITE_OVER$dest_x$dest_y );
                
$wm->destroy();
            } else {
                
$watermark imagecreatefrompng$path_watermark );

                
$watermark_width  imagesx($watermark);
                
$watermark_height imagesy($watermark);

                switch(
osc_watermark_place()) {
                    case 
'tl':
                        
$dest_x 0;
                        
$dest_y 0;
                        break;
                    case 
'tr':
                        
$dest_x $this->_width $watermark_width;
                        
$dest_y 0;
                        break;
                    case 
'bl':
                        
$dest_x 0;
                        
$dest_y $this->_height $watermark_height;
                        break;
                    case 
'br':
                        
$dest_x $this->_width $watermark_width;
                        
$dest_y $this->_height $watermark_height;
                        break;
                    default:
                        
$dest_x = ($this->_width-$watermark_width)/2;
                        
$dest_y = ($this->_height-$watermark_height)/2;
                        break;
                }

                
$this->_imagecopymerge_alpha($this->im$watermark$dest_x$dest_y00$watermark_width$watermark_height100);
                
imagedestroy($watermark);
            }
            return 
$this;
        }



        private function 
_imagecopymerge_alpha(&$dst_im$src_im$dst_x$dst_y$src_x$src_y$src_w$src_h$pct$trans NULL)
        {
            
imagealphablending$dst_imfalse );
            
imagesavealpha$dst_imtrue );

            
$dst_w imagesx($dst_im);
            
$dst_h imagesy($dst_im);

            
$src_x max($src_x0);
            
$src_y max($src_y0);
            
$dst_x max($dst_x0);
            
$dst_y max($dst_y0);
            if (
$dst_x $src_w $dst_w)
                
$src_w $dst_w $dst_x;
            if (
$dst_y $src_h $dst_h)
                
$src_h $dst_h $dst_y;

            for(
$x_offset 0$x_offset $src_w$x_offset++) {
                for(
$y_offset 0$y_offset $src_h$y_offset++) {
                    
$srccolor imagecolorsforindex($src_imimagecolorat($src_im$src_x $x_offset$src_y $y_offset));
                    
$dstcolor imagecolorsforindex($dst_imimagecolorat($dst_im$dst_x $x_offset$dst_y $y_offset));

                    if (
is_null($trans) || ($srccolor !== $trans))
                    {
                        
$src_a $srccolor['alpha'] * $pct 100;
                        
// blend
                        
$src_a 127 $src_a;
                        
$dst_a 127 $dstcolor['alpha'];
                        
$dst_r = ($srccolor['red'] * $src_a $dstcolor['red'] * $dst_a * (127 $src_a) / 127) / 127;
                        
$dst_g = ($srccolor['green'] * $src_a $dstcolor['green'] * $dst_a * (127 $src_a) / 127) / 127;
                        
$dst_b = ($srccolor['blue'] * $src_a $dstcolor['blue'] * $dst_a * (127 $src_a) / 127) / 127;
                        
$dst_a 127 - ($src_a $dst_a * (127 $src_a) / 127);
                        
$color imagecolorallocatealpha($dst_im$dst_r$dst_g$dst_b$dst_a);

                        if (!
imagesetpixel($dst_im$dst_x $x_offset$dst_y $y_offset$color))
                            return 
false;
                        
imagecolordeallocate($dst_im$color);
                    }
                }
            }
            return 
true;
        }
    }


if(!
function_exists('imageflip')) {
    function 
imageflip(&$image$x 0$y 0$width null$height null)
    {
        if (
$width  1$width  imagesx($image);
        if (
$height 1$height imagesy($image);
        
// Truecolor provides better results, if possible.
        
if (function_exists('imageistruecolor') && imageistruecolor($image))
        {
            
$tmp imagecreatetruecolor(1$height);
        }
        else
        {
            
$tmp imagecreate(1$height);
        }
        
$x2 $x $width 1;
        for (
$i = (int) floor(($width 1) / 2); $i >= 0$i--)
        {
            
// Backup right stripe.
            
imagecopy($tmp,   $image0,        0,  $x2 $i$y1$height);
            
// Copy left stripe to the right.
            
imagecopy($image$image$x2 $i$y$x $i,  $y1$height);
            
// Copy backuped right stripe to the left.
            
imagecopy($image$tmp,   $x $i,  $y0,        0,  1$height);
        }
        
imagedestroy($tmp);
        return 
$image;
    }
    
define('IMG_FLIP_HORIZONTAL'0);
}
Онлайн: 1
Реклама