You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							476 lines
						
					
					
						
							14 KiB
						
					
					
				
			
		
		
	
	
							476 lines
						
					
					
						
							14 KiB
						
					
					
				<?php
 | 
						|
/* For licensing terms, see /license.txt */
 | 
						|
 | 
						|
/**
 | 
						|
 * Image class
 | 
						|
 * This class provides a layer to manage images
 | 
						|
 * @author Julio Montoya <gugli100@gmail.com>
 | 
						|
 * @package chamilo.include.image
 | 
						|
 * @todo move in a DB configuration setting
 | 
						|
 */
 | 
						|
class Image
 | 
						|
{
 | 
						|
    public $image_wrapper = null;
 | 
						|
 | 
						|
    /**
 | 
						|
     * Image constructor.
 | 
						|
     * @param string $path
 | 
						|
     */
 | 
						|
    public function __construct($path)
 | 
						|
    {
 | 
						|
        $path = preg_match(VALID_WEB_PATH, $path) ? (api_is_internal_path(
 | 
						|
            $path
 | 
						|
        ) ? api_get_path(TO_SYS, $path) : $path) : $path;
 | 
						|
        if (IMAGE_PROCESSOR == 'gd') {
 | 
						|
            $this->image_wrapper = new GDWrapper($path);
 | 
						|
        } else {
 | 
						|
            if (class_exists('Imagick')) {
 | 
						|
                $this->image_wrapper = new ImagickWrapper($path);
 | 
						|
            } else {
 | 
						|
                Display::display_warning_message('Class Imagick not found');
 | 
						|
                exit;
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    public function resize($max_size_for_picture) {
 | 
						|
        $image_size = $this->get_image_size($this->image_wrapper->path);
 | 
						|
        $width = $image_size['width'];
 | 
						|
        $height = $image_size['height'];
 | 
						|
        if ($width >= $height) {
 | 
						|
            if ($width >= $max_size_for_picture) {
 | 
						|
                // scale height
 | 
						|
                $new_height = round($height * ($max_size_for_picture / $width));
 | 
						|
                $this->image_wrapper->resize($max_size_for_picture, $new_height, 0);
 | 
						|
            }
 | 
						|
        } else { // height > $width
 | 
						|
            if ($height >= $max_size_for_picture) {
 | 
						|
                // scale width
 | 
						|
                $new_width = round($width * ($max_size_for_picture / $height));
 | 
						|
                 $this->image_wrapper->resize($new_width, $max_size_for_picture, 0);
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
    
 | 
						|
    public function crop($cropParameters) {
 | 
						|
        $image_size = $this->get_image_size($this->image_wrapper->path);
 | 
						|
        $src_width = $image_size['width'];
 | 
						|
        $src_height = $image_size['height'];
 | 
						|
        $cropParameters = explode(",", $cropParameters);
 | 
						|
        $x = intval($cropParameters[0]);
 | 
						|
        $y = intval($cropParameters[1]);
 | 
						|
        $width = intval($cropParameters[2]);
 | 
						|
        $height = intval($cropParameters[3]);
 | 
						|
 | 
						|
        $image = $this->image_wrapper->crop($x, $y, $width, $height, $src_width, $src_height);
 | 
						|
        return $image;
 | 
						|
    }
 | 
						|
 | 
						|
    public function send_image(
 | 
						|
        $file = '',
 | 
						|
        $compress = -1,
 | 
						|
        $convert_file_to = null
 | 
						|
    ) {
 | 
						|
        return $this->image_wrapper->send_image(
 | 
						|
            $file,
 | 
						|
            $compress,
 | 
						|
            $convert_file_to
 | 
						|
        );
 | 
						|
    }
 | 
						|
 | 
						|
    public function get_image_size()
 | 
						|
    {
 | 
						|
        return $this->image_wrapper->get_image_size();
 | 
						|
    }
 | 
						|
 | 
						|
    public function get_image_info()
 | 
						|
    {
 | 
						|
        return $this->image_wrapper->get_image_info();
 | 
						|
    }
 | 
						|
 | 
						|
    public function convert2bw()
 | 
						|
    {
 | 
						|
        $this->image_wrapper->convert2bw();
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * Image wrapper class
 | 
						|
 *
 | 
						|
 * @package chamilo.include.image
 | 
						|
 */
 | 
						|
abstract class ImageWrapper
 | 
						|
{
 | 
						|
    public $debug = true;
 | 
						|
    public $path;
 | 
						|
    public $width;
 | 
						|
    public $height;
 | 
						|
    public $type;
 | 
						|
    public $allowed_extensions = array('jpeg', 'jpg', 'png', 'gif');
 | 
						|
    public $image_validated = false;
 | 
						|
 | 
						|
    public function __construct($path)
 | 
						|
    {
 | 
						|
        if (empty($path)) {
 | 
						|
            return false;
 | 
						|
        }
 | 
						|
        $this->path = preg_match(VALID_WEB_PATH, $path) ? (api_is_internal_path($path) ? api_get_path(TO_SYS, $path) : $path) : $path;
 | 
						|
        $this->set_image_wrapper();  //Creates image obj
 | 
						|
    }
 | 
						|
 | 
						|
    abstract function set_image_wrapper();
 | 
						|
    abstract function fill_image_info();
 | 
						|
    abstract function get_image_size();
 | 
						|
    abstract function resize($thumbw, $thumbh, $border, $specific_size = false);
 | 
						|
    abstract function crop($x, $y, $width, $height, $src_width, $src_height);
 | 
						|
    abstract function send_image($file = '', $compress = -1, $convert_file_to = null);
 | 
						|
 | 
						|
    public function get_image_info()
 | 
						|
    {
 | 
						|
        return array(
 | 
						|
            'width' => $this->width,
 | 
						|
            'height' => $this->height,
 | 
						|
            'type' => $this->type,
 | 
						|
        );
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * Imagick Chamilo wrapper
 | 
						|
 *
 | 
						|
 * @author jmontoya
 | 
						|
 *
 | 
						|
 * @package chamilo.include.image
 | 
						|
 */
 | 
						|
class ImagickWrapper extends ImageWrapper
 | 
						|
{
 | 
						|
    public $image;
 | 
						|
    public $filter = Imagick::FILTER_LANCZOS;
 | 
						|
 | 
						|
    public function __construct($path)
 | 
						|
    {
 | 
						|
          parent::__construct($path);
 | 
						|
    }
 | 
						|
 | 
						|
    public function set_image_wrapper()
 | 
						|
    {
 | 
						|
        if ($this->debug) error_log('Image::set_image_wrapper loaded');
 | 
						|
        try {
 | 
						|
            if (file_exists($this->path)) {
 | 
						|
                $this->image     = new Imagick($this->path);
 | 
						|
 | 
						|
                if ($this->image) {
 | 
						|
                    $this->fill_image_info(); //Fills height, width and type
 | 
						|
                }
 | 
						|
            } else {
 | 
						|
                if ($this->debug) error_log('Image::image does not exist');
 | 
						|
            }
 | 
						|
        } catch(ImagickException $e) {
 | 
						|
            if ($this->debug) error_log($e->getMessage());
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    public function fill_image_info()
 | 
						|
    {
 | 
						|
        $image_info      = $this->image->identifyImage();
 | 
						|
 | 
						|
        $this->width     = $image_info['geometry']['width'];
 | 
						|
        $this->height    = $image_info['geometry']['height'];
 | 
						|
        $this->type      = strtolower($this->image->getImageFormat());
 | 
						|
 | 
						|
        if (in_array($this->type, $this->allowed_extensions)) {
 | 
						|
            $this->image_validated = true;
 | 
						|
            if ($this->debug) error_log('image_validated true');
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
	public function get_image_size()
 | 
						|
    {
 | 
						|
		$imagesize = array('width'=>0,'height'=>0);
 | 
						|
	    if ($this->image_validated) {
 | 
						|
            $imagesize = $this->image->getImageGeometry();
 | 
						|
	    }
 | 
						|
	    return $imagesize;
 | 
						|
	}
 | 
						|
 | 
						|
	//@todo implement border logic case for Imagick
 | 
						|
	public function resize($thumbw, $thumbh, $border, $specific_size = false)
 | 
						|
    {
 | 
						|
	    if (!$this->image_validated) return false;
 | 
						|
 | 
						|
        if ($specific_size) {
 | 
						|
            $width = $thumbw;
 | 
						|
            $height = $thumbh;
 | 
						|
        } else {
 | 
						|
            $scale  = ($this->width > 0 && $this->height > 0) ? min($thumbw / $this->width, $thumbh / $this->height) : 0;
 | 
						|
            $width  = (int)($this->width * $scale);
 | 
						|
            $height = (int)($this->height * $scale);
 | 
						|
        }
 | 
						|
		$result = $this->image->resizeImage($width, $height, $this->filter, 1);
 | 
						|
		$this->width  = $thumbw;
 | 
						|
		$this->height = $thumbh;
 | 
						|
	}
 | 
						|
    
 | 
						|
    /**
 | 
						|
     * @author José Loguercio <jose.loguercio@beeznest.com>
 | 
						|
     * @param int $x coordinate of the cropped region top left corner
 | 
						|
     * @param int $y coordinate of the cropped region top left corner
 | 
						|
     * @param int $width the width of the crop
 | 
						|
     * @param int $height the height of the crop
 | 
						|
     * @param int $src_width the source width of the original image
 | 
						|
     * @param int $src_height the source height of the original image
 | 
						|
     */
 | 
						|
    
 | 
						|
    public function crop($x, $y, $width, $height, $src_width, $src_height) {
 | 
						|
        if (!$this->image_validated) return false;
 | 
						|
        $this->image->cropimage($width, $height, $x, $y);
 | 
						|
		$this->width  = $width;
 | 
						|
		$this->height = $height;
 | 
						|
    }
 | 
						|
 | 
						|
    public function send_image($file = '', $compress = -1, $convert_file_to = null)
 | 
						|
    {
 | 
						|
        if (!$this->image_validated) return false;
 | 
						|
        $type = $this->type;
 | 
						|
        if (!empty($convert_file_to) && in_array($convert_file_to, $this->allowed_extensions)) {
 | 
						|
            $type = $convert_file_to;
 | 
						|
        }
 | 
						|
		switch ($type) {
 | 
						|
		    case 'jpeg':
 | 
						|
			case 'jpg':
 | 
						|
				if (!$file) header("Content-type: image/jpeg");
 | 
						|
				break;
 | 
						|
			case 'png':
 | 
						|
				if (!$file) header("Content-type: image/png");
 | 
						|
				break;
 | 
						|
			case 'gif':
 | 
						|
				if (!$file) header("Content-type: image/gif");
 | 
						|
				break;
 | 
						|
		}
 | 
						|
		$result = false;
 | 
						|
		try {
 | 
						|
		    $result = $this->image->writeImage($file);
 | 
						|
		} catch(ImagickException $e) {
 | 
						|
            if ($this->debug) error_log($e->getMessage());
 | 
						|
        }
 | 
						|
 | 
						|
		if (!$file) {
 | 
						|
		    echo $this->image;
 | 
						|
		    $this->image->clear();
 | 
						|
            $this->image->destroy();
 | 
						|
		} else {
 | 
						|
		    $this->image->clear();
 | 
						|
            $this->image->destroy();
 | 
						|
		    return $result;
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * php-gd wrapper
 | 
						|
 * @package chamilo.include.image
 | 
						|
 */
 | 
						|
class GDWrapper extends ImageWrapper
 | 
						|
{
 | 
						|
    public $bg;
 | 
						|
 | 
						|
    function __construct($path) {
 | 
						|
        parent::__construct($path);
 | 
						|
    }
 | 
						|
 | 
						|
    public function set_image_wrapper()
 | 
						|
    {
 | 
						|
        $handler = null;
 | 
						|
        $this->fill_image_info();
 | 
						|
 | 
						|
        switch ($this->type) {
 | 
						|
        	case 0:
 | 
						|
        		$handler = false;
 | 
						|
        		break;
 | 
						|
		    case 1 :
 | 
						|
                $handler = @imagecreatefromgif($this->path);
 | 
						|
                $this->type = 'gif';
 | 
						|
                break;
 | 
						|
		    case 2 :
 | 
						|
                $handler = @imagecreatefromjpeg($this->path);
 | 
						|
                $this->type = 'jpg';
 | 
						|
                break;
 | 
						|
		    case 3 :
 | 
						|
		        $handler = @imagecreatefrompng($this->path);
 | 
						|
		        $this->type = 'png';
 | 
						|
		        break;
 | 
						|
        }
 | 
						|
        if ($handler) {
 | 
						|
            $this->image_validated = true;
 | 
						|
            $this->bg = $handler;
 | 
						|
            @imagealphablending($this->bg, false);
 | 
						|
            @imagesavealpha($this->bg, true);
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    public function get_image_size()
 | 
						|
    {
 | 
						|
        $return_array = array('width'=>0,'height'=>0);
 | 
						|
        if ($this->image_validated) {
 | 
						|
	        $return_array = array('width'=>$this->width,'height'=>$this->height);
 | 
						|
        }
 | 
						|
        return $return_array;
 | 
						|
	}
 | 
						|
 | 
						|
    public function fill_image_info()
 | 
						|
    {
 | 
						|
    	if (file_exists($this->path)) {
 | 
						|
	        $image_info     = getimagesize($this->path);
 | 
						|
			$this->width    = $image_info[0];
 | 
						|
			$this->height   = $image_info[1];
 | 
						|
			$this->type     = $image_info[2];
 | 
						|
    	} else {
 | 
						|
    		$this->width    = 0;
 | 
						|
    		$this->height   = 0;
 | 
						|
    		$this->type     = 0;
 | 
						|
    	}
 | 
						|
    }
 | 
						|
 | 
						|
    public function resize($thumbw, $thumbh, $border, $specific_size = false)
 | 
						|
    {
 | 
						|
        if (!$this->image_validated) return false;
 | 
						|
		if ($border == 1) {
 | 
						|
            if ($specific_size) {
 | 
						|
                $width = $thumbw;
 | 
						|
                $height = $thumbh;
 | 
						|
            } else {
 | 
						|
                $scale = min($thumbw / $this->width, $thumbh / $this->height);
 | 
						|
                $width = (int)($this->width * $scale);
 | 
						|
                $height = (int)($this->height * $scale);
 | 
						|
            }
 | 
						|
			$deltaw = (int)(($thumbw - $width) / 2);
 | 
						|
			$deltah = (int)(($thumbh - $height) / 2);
 | 
						|
			$dst_img = @ImageCreateTrueColor($thumbw, $thumbh);
 | 
						|
            		@imagealphablending($dst_img, false);
 | 
						|
		        @imagesavealpha($dst_img, true);
 | 
						|
			if (!empty($this->color)) {
 | 
						|
				@imagefill($dst_img, 0, 0, $this->color);
 | 
						|
			}
 | 
						|
			$this->width = $thumbw;
 | 
						|
			$this->height = $thumbh;
 | 
						|
		} elseif ($border == 0) {
 | 
						|
            if ($specific_size) {
 | 
						|
                $width = $thumbw;
 | 
						|
                $height = $thumbh;
 | 
						|
            } else {
 | 
						|
                $scale = ($this->width > 0 && $this->height > 0) ? min($thumbw / $this->width, $thumbh / $this->height) : 0;
 | 
						|
                $width  = (int)($this->width * $scale);
 | 
						|
                $height = (int)($this->height * $scale);
 | 
						|
            }
 | 
						|
			$deltaw = 0;
 | 
						|
			$deltah = 0;
 | 
						|
			$dst_img = @ImageCreateTrueColor($width, $height);
 | 
						|
            		@imagealphablending($dst_img, false);
 | 
						|
		        @imagesavealpha($dst_img, true);
 | 
						|
			$this->width = $width;
 | 
						|
			$this->height = $height;
 | 
						|
		}
 | 
						|
		$src_img = $this->bg;
 | 
						|
		@ImageCopyResampled($dst_img, $src_img, $deltaw, $deltah, 0, 0, $width, $height, ImageSX($src_img), ImageSY($src_img));
 | 
						|
		$this->bg = $dst_img;
 | 
						|
		@imagedestroy($src_img);
 | 
						|
	}
 | 
						|
    
 | 
						|
    /**
 | 
						|
     * @author José Loguercio <jose.loguercio@beeznest.com>
 | 
						|
     * @param int $x coordinate of the cropped region top left corner
 | 
						|
     * @param int $y coordinate of the cropped region top left corner
 | 
						|
     * @param int $width the width of the crop
 | 
						|
     * @param int $height the height of the crop
 | 
						|
     * @param int $src_width the source width of the original image
 | 
						|
     * @param int $src_height the source height of the original image
 | 
						|
     */
 | 
						|
    public function crop($x, $y, $width, $height, $src_width, $src_height) {
 | 
						|
        if (!$this->image_validated) return false;
 | 
						|
        $this->width = $width;
 | 
						|
		$this->height = $height;
 | 
						|
        $src = null;
 | 
						|
        $dest = @imagecreatetruecolor($width, $height);
 | 
						|
        $type = $this->type;
 | 
						|
        switch ($type) {
 | 
						|
            case 'jpeg' :
 | 
						|
            case 'jpg' :
 | 
						|
                $src = @imagecreatefromjpeg($this->path);
 | 
						|
                @imagecopy($dest, $src, 0, 0, $x, $y, $src_width, $src_height);
 | 
						|
                @imagejpeg($dest, $this->path);
 | 
						|
                break;
 | 
						|
		    case 'png' :
 | 
						|
                $src = @imagecreatefrompng($this->path);
 | 
						|
                @imagecopy($dest, $src, 0, 0, $x, $y, $src_width, $src_height);
 | 
						|
                @imagepng($dest, $this->path);
 | 
						|
                break;
 | 
						|
		    case 'gif' :
 | 
						|
		        $src = @imagecreatefromgif($this->path);
 | 
						|
                @imagecopy($dest, $src, 0, 0, $x, $y, $src_width, $src_height);
 | 
						|
                @imagegif($dest, $this->path);
 | 
						|
		        break;
 | 
						|
            default: return 0;
 | 
						|
        }
 | 
						|
        @imagedestroy($dest);
 | 
						|
        @imagedestroy($src);
 | 
						|
    }
 | 
						|
 | 
						|
	public function send_image($file = '', $compress = -1, $convert_file_to = null)
 | 
						|
    {
 | 
						|
	    if (!$this->image_validated) return false;
 | 
						|
        $compress = (int)$compress;
 | 
						|
        $type = $this->type;
 | 
						|
        if (!empty($convert_file_to) && in_array($convert_file_to, $this->allowed_extensions)) {
 | 
						|
            $type = $convert_file_to;
 | 
						|
        }
 | 
						|
		switch ($type) {
 | 
						|
		    case 'jpeg':
 | 
						|
			case 'jpg':
 | 
						|
				if (!$file) header("Content-type: image/jpeg");
 | 
						|
				if ($compress == -1) $compress = 100;
 | 
						|
				return imagejpeg($this->bg, $file, $compress);
 | 
						|
				break;
 | 
						|
			case 'png':
 | 
						|
				if (!$file) header("Content-type: image/png");
 | 
						|
				if ($compress != -1) {
 | 
						|
					@imagetruecolortopalette($this->bg, true, $compress);
 | 
						|
				}
 | 
						|
				return imagepng($this->bg, $file, $compress);
 | 
						|
				break;
 | 
						|
			case 'gif':
 | 
						|
				if (!$file) header("Content-type: image/gif");
 | 
						|
				if ($compress != -1) {
 | 
						|
					@imagetruecolortopalette($this->bg, true, $compress);
 | 
						|
				}
 | 
						|
				return imagegif($this->bg, $file, $compress);
 | 
						|
				break;
 | 
						|
			default: return 0;
 | 
						|
		}
 | 
						|
		// TODO: Occupied memory is not released, because the following fragment of code is actually dead.
 | 
						|
		@imagedestroy($this->bg);
 | 
						|
	}
 | 
						|
 | 
						|
    /**
 | 
						|
     * Convert image to black & white
 | 
						|
     */
 | 
						|
    function convert2bw()
 | 
						|
    {
 | 
						|
        if (!$this->image_validated) return false;
 | 
						|
 | 
						|
        $dest_img = imagecreatetruecolor(imagesx($this->bg), imagesy($this->bg));
 | 
						|
        /* copy ignore the transparent color
 | 
						|
         * so that we can use black (0,0,0) as transparent, which is what
 | 
						|
         * the image is filled with when created.
 | 
						|
         */
 | 
						|
        $transparent = imagecolorallocate($dest_img, 0,0,0);
 | 
						|
        imagealphablending($dest_img, false);
 | 
						|
        imagesavealpha($dest_img, true);
 | 
						|
        imagecolortransparent($dest_img, $transparent);
 | 
						|
        imagecopy($dest_img, $this->bg, 0,0, 0, 0,imagesx($this->bg), imagesx($this->bg));
 | 
						|
        imagefilter($dest_img, IMG_FILTER_GRAYSCALE);
 | 
						|
        $this->bg = $dest_img;
 | 
						|
 | 
						|
        return true;
 | 
						|
    }
 | 
						|
}
 | 
						|
 |