123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628 |
- <?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)
- {
- if (IMAGE_PROCESSOR == 'gd') {
- $this->image_wrapper = new GDWrapper($path);
- } else {
- if (class_exists('Imagick')) {
- $this->image_wrapper = new ImagickWrapper($path);
- } else {
- echo Display::return_message(
- 'Class Imagick not found',
- 'warning'
- );
- 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
- );
- }
- }
- }
- /**
- * @param $cropParameters
- *
- * @return bool
- */
- 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);
- if (isset($cropParameters[0]) && isset($cropParameters[1])) {
- $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;
- }
- return false;
- }
- /**
- * @param string $file
- * @param int $compress
- * @param null $convert_file_to
- *
- * @return bool
- */
- public function send_image(
- $file = '',
- $compress = -1,
- $convert_file_to = null
- ) {
- return $this->image_wrapper->send_image(
- $file,
- $compress,
- $convert_file_to
- );
- }
- /**
- * @return array
- */
- public function get_image_size()
- {
- return $this->image_wrapper->get_image_size();
- }
- /**
- * @return array
- */
- 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 = ['jpeg', 'jpg', 'png', 'gif'];
- public $image_validated = false;
- public function __construct($path)
- {
- if (empty($path)) {
- return false;
- }
- $this->path = $path;
- $this->set_image_wrapper(); //Creates image obj
- }
- abstract public function set_image_wrapper();
- abstract public function fill_image_info();
- abstract public function get_image_size();
- abstract public function resize($thumbw, $thumbh, $border, $specific_size = false);
- abstract public function crop($x, $y, $width, $height, $src_width, $src_height);
- abstract public function send_image($file = '', $compress = -1, $convert_file_to = null);
- /**
- * @return array
- */
- public function get_image_info()
- {
- return [
- '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;
- /**
- * ImagickWrapper constructor.
- *
- * @param $path
- */
- 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 = ['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
- *
- * @return bool
- */
- 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;
- return true;
- }
- 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;
- /**
- * GDWrapper constructor.
- *
- * @param $path
- */
- public 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);
- }
- }
- /**
- * @return array
- */
- public function get_image_size()
- {
- $return_array = ['width' => 0, 'height' => 0];
- if ($this->image_validated) {
- $return_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);
- @imagealphablending($dest, false);
- @imagesavealpha($dest, true);
- @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);
- }
- /**
- * @param string $file
- * @param int $compress
- * @param null $convert_file_to
- *
- * @return bool|int
- */
- 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.
- */
- public 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;
- }
- }
|