diff options
author | patdenice <patdenice@piwigo.org> | 2011-04-27 17:03:25 +0000 |
---|---|---|
committer | patdenice <patdenice@piwigo.org> | 2011-04-27 17:03:25 +0000 |
commit | d95ddb7c6146157418f7735995a2b43ef3d2c8fb (patch) | |
tree | 1ed4715f98e323345393602290d4a679efe295b3 | |
parent | c3a0ff6b886463cebd3959bae07dd87726bff24c (diff) |
feature:2284
Create a class to manipulate images.
git-svn-id: http://piwigo.org/svn/trunk@10641 68402e56-0260-453c-a942-63ccdbb3a9ee
-rw-r--r-- | admin/include/functions_upload.inc.php | 354 | ||||
-rw-r--r-- | admin/include/image.class.php | 627 | ||||
-rw-r--r-- | admin/photos_add.php | 1 | ||||
-rw-r--r-- | admin/photos_add_settings.php | 2 | ||||
-rw-r--r-- | include/config_default.inc.php | 9 | ||||
-rw-r--r-- | include/ws_functions.inc.php | 21 | ||||
-rw-r--r-- | ws.php | 2 |
7 files changed, 668 insertions, 348 deletions
diff --git a/admin/include/functions_upload.inc.php b/admin/include/functions_upload.inc.php index 4fe8ce76b..5ad71b308 100644 --- a/admin/include/functions_upload.inc.php +++ b/admin/include/functions_upload.inc.php @@ -22,6 +22,7 @@ // +-----------------------------------------------------------------------+ include_once(PHPWG_ROOT_PATH.'admin/include/functions.php'); +include_once(PHPWG_ROOT_PATH.'admin/include/image.class.php'); // add default event handler for image and thumbnail resize add_event_handler('upload_image_resize', 'pwg_image_resize', EVENT_HANDLER_PRIORITY_NEUTRAL, 7); @@ -362,18 +363,18 @@ SELECT rename($file_path, $high_path); $high_infos = pwg_image_infos($high_path); - trigger_event( - 'upload_image_resize', - false, - $high_path, + $img = new pwg_image($high_path); + + $img->pwg_resize( $file_path, $conf['upload_form_websize_maxwidth'], $conf['upload_form_websize_maxheight'], $conf['upload_form_websize_quality'], + $conf['upload_form_automatic_rotation'], false ); - if (is_imagick()) + if ($img->library != 'gd') { if ($conf['upload_form_hd_keep']) { @@ -383,13 +384,12 @@ SELECT if ($need_resize) { - pwg_image_resize( - false, - $high_path, + $img->pwg_resize( $high_path, $conf['upload_form_hd_maxwidth'], $conf['upload_form_hd_maxheight'], $conf['upload_form_hd_quality'], + $conf['upload_form_automatic_rotation'], false ); $high_infos = pwg_image_infos($high_path); @@ -402,6 +402,7 @@ SELECT $high_infos = null; } } + $img->destroy(); } $file_infos = pwg_image_infos($file_path); @@ -409,19 +410,17 @@ SELECT $thumb_path = file_path_for_type($file_path, 'thumb'); $thumb_dir = dirname($thumb_path); prepare_directory($thumb_dir); - - trigger_event( - 'upload_thumbnail_resize', - false, - $file_path, + + $img = new pwg_image($file_path); + $img->pwg_resize( $thumb_path, $conf['upload_form_thumb_maxwidth'], $conf['upload_form_thumb_maxheight'], $conf['upload_form_thumb_quality'], - true, - $conf['upload_form_thumb_crop'], - $conf['upload_form_thumb_follow_orientation'] + $conf['upload_form_automatic_rotation'], + true ); + $img->destroy(); $thumb_infos = pwg_image_infos($thumb_path); @@ -567,307 +566,6 @@ function need_resize($image_filepath, $max_width, $max_height) return false; } -function get_resize_dimensions($width, $height, $max_width, $max_height, $rotation=null) -{ - $rotate_for_dimensions = false; - if (isset($rotation) and in_array(abs($rotation), array(90, 270))) - { - $rotate_for_dimensions = true; - } - - if ($rotate_for_dimensions) - { - list($width, $height) = array($height, $width); - } - - $ratio_width = $width / $max_width; - $ratio_height = $height / $max_height; - $destination_width = $width; - $destination_height = $height; - - // maximal size exceeded ? - if ($ratio_width > 1 or $ratio_height > 1) - { - if ($ratio_width < $ratio_height) - { - $destination_width = round($width / $ratio_height); - $destination_height = $max_height; - } - else - { - $destination_width = $max_width; - $destination_height = round($height / $ratio_width); - } - } - - if ($rotate_for_dimensions) - { - list($destination_width, $destination_height) = array($destination_height, $destination_width); - } - - return array( - 'width' => $destination_width, - 'height'=> $destination_height, - ); -} - -function pwg_image_resize($result, $source_filepath, $destination_filepath, $max_width, $max_height, $quality, $strip_metadata=false, $crop=false, $follow_orientation=true) -{ - if ($result !== false) - { - //someone hooked us - so we skip - return $result; - } - - $extension = strtolower(get_extension($source_filepath)); - - if (is_imagick() and $extension != 'gif') - { - return pwg_image_resize_im($source_filepath, $destination_filepath, $max_width, $max_height, $quality, $strip_metadata, $crop, $follow_orientation); - } - else - { - return pwg_image_resize_gd($source_filepath, $destination_filepath, $max_width, $max_height, $quality, $crop, $follow_orientation); - } -} - -function pwg_image_resize_gd($source_filepath, $destination_filepath, $max_width, $max_height, $quality, $crop=false, $follow_orientation=true) -{ - if (!function_exists('gd_info')) - { - return false; - } - - $starttime = get_moment(); - $gd_info = gd_info(); - - // extension of the picture filename - $extension = strtolower(get_extension($source_filepath)); - - $source_image = null; - if (in_array($extension, array('jpg', 'jpeg'))) - { - $source_image = imagecreatefromjpeg($source_filepath); - } - else if ($extension == 'png') - { - $source_image = imagecreatefrompng($source_filepath); - } - elseif ($extension == 'gif' and $gd_info['GIF Read Support'] and $gd_info['GIF Create Support']) - { - $source_image = imagecreatefromgif($source_filepath); - } - else - { - die('[GD] unsupported file extension'); - } - - $rotation = null; - if (function_exists('imagerotate')) - { - $rotation = get_rotation_angle($source_filepath); - } - - // width/height - $source_width = imagesx($source_image); - $source_height = imagesy($source_image); - - // Crop - if ($crop) - { - $coord = get_crop_coord($source_width, $source_height, $max_width, $max_height, $follow_orientation); - } - - $resize_dimensions = get_resize_dimensions($source_width, $source_height, $max_width, $max_height, $rotation); - - // testing on height is useless in theory: if width is unchanged, there - // should be no resize, because width/height ratio is not modified. - if ($resize_dimensions['width'] == $source_width and $resize_dimensions['height'] == $source_height) - { - // the image doesn't need any resize! We just copy it to the destination - copy($source_filepath, $destination_filepath); - return get_resize_result($source_filepath, $destination_filepath, $resize_dimensions['width'], $resize_dimensions['height'], $starttime, 'GD'); - } - - $destination_image = imagecreatetruecolor($resize_dimensions['width'], $resize_dimensions['height']); - - imagecopyresampled( - $destination_image, - $source_image, - 0, - 0, - $crop ? $coord['x'] : 0, - $crop ? $coord['y'] : 0, - $resize_dimensions['width'], - $resize_dimensions['height'], - $source_width, - $source_height - ); - - // rotation occurs only on resized photo to avoid useless memory use - if (isset($rotation)) - { - $destination_image = imagerotate($destination_image, $rotation, 0); - } - - $extension = strtolower(get_extension($destination_filepath)); - if ($extension == 'png') - { - imagepng($destination_image, $destination_filepath); - } - elseif ($extension == 'gif') - { - imagegif($destination_image, $destination_filepath); - } - else - { - imagejpeg($destination_image, $destination_filepath, $quality); - } - // freeing memory ressources - imagedestroy($source_image); - imagedestroy($destination_image); - - // everything should be OK if we are here! - return get_resize_result($source_filepath, $destination_filepath, $resize_dimensions['width'], $resize_dimensions['height'], $starttime, 'GD'); -} - -function pwg_image_resize_im($source_filepath, $destination_filepath, $max_width, $max_height, $quality, $strip_metadata=false, $crop=false, $follow_orientation=true) -{ - $starttime = get_moment(); - - // extension of the picture filename - $extension = strtolower(get_extension($source_filepath)); - if (!in_array($extension, array('jpg', 'jpeg', 'png'))) - { - die('[Imagick] unsupported file extension'); - } - - $image = new Imagick($source_filepath); - - $rotation = get_rotation_angle($source_filepath); - - // width/height - $source_width = $image->getImageWidth(); - $source_height = $image->getImageHeight(); - - // Crop - if ($crop) - { - $coord = get_crop_coord($source_width, $source_height, $max_width, $max_height, $follow_orientation); - $image->cropImage($source_width, $source_height, $coord['x'], $coord['y']); - } - - $resize_dimensions = get_resize_dimensions($source_width, $source_height, $max_width, $max_height, $rotation); - - // testing on height is useless in theory: if width is unchanged, there - // should be no resize, because width/height ratio is not modified. - if ($resize_dimensions['width'] == $source_width and $resize_dimensions['height'] == $source_height) - { - // the image doesn't need any resize! We just copy it to the destination - copy($source_filepath, $destination_filepath); - get_resize_result($source_filepath, $destination_filepath, $resize_dimensions['width'], $resize_dimensions['height'], $starttime, 'ImageMagick'); - } - - $image->setImageCompressionQuality($quality); - $image->setInterlaceScheme(Imagick::INTERLACE_LINE); - - if ($strip_metadata) - { - // we save a few kilobytes. For example a thumbnail with metadata - // weights 25KB, without metadata 7KB. - $image->stripImage(); - } - - $image->resizeImage($resize_dimensions['width'], $resize_dimensions['height'], Imagick::FILTER_LANCZOS, 0.9); - - if (isset($rotation)) - { - $image->rotateImage(new ImagickPixel(), -$rotation); - $image->setImageOrientation(Imagick::ORIENTATION_TOPLEFT); - } - - $image->writeImage($destination_filepath); - $image->destroy(); - - // everything should be OK if we are here! - return get_resize_result($source_filepath, $destination_filepath, $resize_dimensions['width'], $resize_dimensions['height'], $starttime, 'ImageMagick'); -} - -function get_rotation_angle($source_filepath) -{ - global $conf; - - if (!$conf['upload_form_automatic_rotation']) - { - return null; - } - - list($width, $height, $type) = getimagesize($source_filepath); - if (IMAGETYPE_JPEG != $type) - { - return null; - } - - if (!function_exists('exif_read_data')) - { - return null; - } - - $rotation = null; - - $exif = exif_read_data($source_filepath); - - if (isset($exif['Orientation']) and preg_match('/^\s*(\d)/', $exif['Orientation'], $matches)) - { - $orientation = $matches[1]; - if (in_array($orientation, array(3, 4))) - { - $rotation = 180; - } - elseif (in_array($orientation, array(5, 6))) - { - $rotation = 270; - } - elseif (in_array($orientation, array(7, 8))) - { - $rotation = 90; - } - } - - return $rotation; -} - -function get_crop_coord(&$source_width, &$source_height, &$max_width, &$max_height, $follow_orientation) -{ - $x = 0; - $y = 0; - - if ($source_width < $source_height and $follow_orientation) - { - list($width, $height) = array($max_height, $max_width); - $max_width = $width; - $max_height = $height; - } - - $img_ratio = $source_width / $source_height; - $dest_ratio = $max_width / $max_height; - - if($dest_ratio > $img_ratio) - { - $destHeight = round($source_width * $max_height / $max_width); - $y = round(($source_height - $destHeight) / 2 ); - $source_height = $destHeight; - } - elseif ($dest_ratio < $img_ratio) - { - $destWidth = round($source_height * $max_width / $max_height); - $x = round(($source_width - $destWidth) / 2 ); - $source_width = $destWidth; - } - - return array('x' => $x, 'y' => $y); -} - function pwg_image_infos($path) { list($width, $height) = getimagesize($path); @@ -963,16 +661,6 @@ function add_upload_error($upload_id, $error_message) array_push($_SESSION['uploads_error'][$upload_id], $error_message); } -function is_imagick() -{ - if (class_exists('Imagick')) - { - return true; - } - - return false; -} - function ready_for_upload_message() { global $conf; @@ -1033,16 +721,4 @@ function file_path_for_type($file_path, $type='thumb') return $file_path; } -function get_resize_result($source_filepath, $destination_filepath, $width, $height, $time, $library) -{ - return array( - 'source' => $source_filepath, - 'destination' => $destination_filepath, - 'width' => $width, - 'height' => $height, - 'size' => floor(filesize($destination_filepath) / 1024).' KB', - 'time' => number_format((get_moment() - $time) * 1000, 2, '.', ' ').' ms', - 'library' => $library, - ); -} ?>
\ No newline at end of file diff --git a/admin/include/image.class.php b/admin/include/image.class.php new file mode 100644 index 000000000..943c2a257 --- /dev/null +++ b/admin/include/image.class.php @@ -0,0 +1,627 @@ +<?php
+// +-----------------------------------------------------------------------+
+// | Piwigo - a PHP based photo gallery |
+// +-----------------------------------------------------------------------+
+// | Copyright(C) 2008-2011 Piwigo Team http://piwigo.org |
+// | Copyright(C) 2003-2008 PhpWebGallery Team http://phpwebgallery.net |
+// | Copyright(C) 2002-2003 Pierrick LE GALL http://le-gall.net/pierrick |
+// +-----------------------------------------------------------------------+
+// | This program is free software; you can redistribute it and/or modify |
+// | it under the terms of the GNU General Public License as published by |
+// | the Free Software Foundation |
+// | |
+// | This program is distributed in the hope that it will be useful, but |
+// | WITHOUT ANY WARRANTY; without even the implied warranty of |
+// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
+// | General Public License for more details. |
+// | |
+// | You should have received a copy of the GNU General Public License |
+// | along with this program; if not, write to the Free Software |
+// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
+// | USA. |
+// +-----------------------------------------------------------------------+
+
+// +-----------------------------------------------------------------------+
+// | Image Interface |
+// +-----------------------------------------------------------------------+
+
+// Define all needed methods for image class
+interface imageInterface
+{
+ function get_width();
+
+ function get_height();
+
+ function set_compression_quality($quality);
+
+ function crop($width, $height, $x, $y);
+
+ function strip();
+
+ function rotate($rotation);
+
+ function resize($width, $height);
+
+ function write($destination_filepath);
+}
+
+// +-----------------------------------------------------------------------+
+// | Main Image Class |
+// +-----------------------------------------------------------------------+
+
+class pwg_image
+{
+ var $image;
+ var $library = '';
+ var $source_filepath = '';
+
+ function __construct($source_filepath, $library=null)
+ {
+ global $conf;
+
+ $this->source_filepath = $source_filepath;
+
+ trigger_action('load_image_library', array(&$this) );
+
+ if (is_object($this->image))
+ {
+ return; // A plugin may have load its own library
+ }
+
+ $extension = strtolower(get_extension($source_filepath));
+
+ if (!in_array($extension, array('jpg', 'jpeg', 'png', 'gif')))
+ {
+ die('[Image] unsupported file extension');
+ }
+
+ if (is_null($library))
+ {
+ $library = $conf['image_library'];
+ }
+
+ // Choose image library
+ switch (strtolower($library))
+ {
+ case 'auto':
+ case 'imagick':
+ if ($extension != 'gif' and self::is_imagick())
+ {
+ $this->library = 'imagick';
+ break;
+ }
+ case 'ext_imagick':
+ if ($extension != 'gif' and self::is_ext_imagick())
+ {
+ $this->library = 'ext_imagick';
+ break;
+ }
+ case 'gd':
+ if (self::is_gd())
+ {
+ $this->library = 'gd';
+ break;
+ }
+ default:
+ if ($library != 'auto')
+ {
+ // Requested library not available. Try another library
+ return self::__construct($source_filepath, 'auto');
+ }
+ die('No image library available on your server.');
+ }
+
+ $class = 'image_'.$this->library;
+ $this->image = new $class($source_filepath);
+ }
+
+ // Unknow methods will be redirected to image object
+ function __call($method, $arguments)
+ {
+ return call_user_func_array(array($this->image, $method), $arguments);
+ }
+
+ // Piwigo resize function
+ function pwg_resize($destination_filepath, $max_width, $max_height, $quality, $automatic_rotation=true, $strip_metadata=false, $crop=false, $follow_orientation=true)
+ {
+ $starttime = get_moment();
+
+ // width/height
+ $source_width = $this->image->get_width();
+ $source_height = $this->image->get_height();
+
+ // Crop image
+ if ($crop)
+ {
+ $x = 0;
+ $y = 0;
+
+ if ($source_width < $source_height and $follow_orientation)
+ {
+ list($max_width, $max_height) = array($max_height, $max_width);
+ }
+
+ $img_ratio = $source_width / $source_height;
+ $dest_ratio = $max_width / $max_height;
+
+ if($dest_ratio > $img_ratio)
+ {
+ $destHeight = round($source_width * $max_height / $max_width);
+ $y = round(($source_height - $destHeight) / 2 );
+ $source_height = $destHeight;
+ }
+ elseif ($dest_ratio < $img_ratio)
+ {
+ $destWidth = round($source_height * $max_width / $max_height);
+ $x = round(($source_width - $destWidth) / 2 );
+ $source_width = $destWidth;
+ }
+
+ $this->image->crop($source_width, $source_height, $x, $y);
+ }
+
+ $rotation = null;
+ if ($automatic_rotation)
+ {
+ $rotation = self::get_rotation_angle($this->source_filepath);
+ }
+ $resize_dimensions = self::get_resize_dimensions($source_width, $source_height, $max_width, $max_height, $rotation);
+
+ // testing on height is useless in theory: if width is unchanged, there
+ // should be no resize, because width/height ratio is not modified.
+ if ($resize_dimensions['width'] == $source_width and $resize_dimensions['height'] == $source_height)
+ {
+ // the image doesn't need any resize! We just copy it to the destination
+ copy($this->source_filepath, $destination_filepath);
+ return $this->get_resize_result($destination_filepath, $resize_dimensions['width'], $resize_dimensions['height'], $starttime);
+ }
+
+ $this->image->set_compression_quality($quality);
+
+ if ($strip_metadata)
+ {
+ // we save a few kilobytes. For example a thumbnail with metadata weights 25KB, without metadata 7KB.
+ $this->image->strip();
+ }
+
+ $this->image->resize($resize_dimensions['width'], $resize_dimensions['height']);
+
+ if (isset($rotation))
+ {
+ $this->image->rotate($rotation);
+ }
+
+ $this->image->write($destination_filepath);
+
+ // everything should be OK if we are here!
+ return $this->get_resize_result($destination_filepath, $resize_dimensions['width'], $resize_dimensions['height'], $starttime);
+ }
+
+ static function get_resize_dimensions($width, $height, $max_width, $max_height, $rotation=null)
+ {
+ $rotate_for_dimensions = false;
+ if (isset($rotation) and in_array(abs($rotation), array(90, 270)))
+ {
+ $rotate_for_dimensions = true;
+ }
+
+ if ($rotate_for_dimensions)
+ {
+ list($width, $height) = array($height, $width);
+ }
+
+ $ratio_width = $width / $max_width;
+ $ratio_height = $height / $max_height;
+ $destination_width = $width;
+ $destination_height = $height;
+
+ // maximal size exceeded ?
+ if ($ratio_width > 1 or $ratio_height > 1)
+ {
+ if ($ratio_width < $ratio_height)
+ {
+ $destination_width = round($width / $ratio_height);
+ $destination_height = $max_height;
+ }
+ else
+ {
+ $destination_width = $max_width;
+ $destination_height = round($height / $ratio_width);
+ }
+ }
+
+ if ($rotate_for_dimensions)
+ {
+ list($destination_width, $destination_height) = array($destination_height, $destination_width);
+ }
+
+ return array(
+ 'width' => $destination_width,
+ 'height'=> $destination_height,
+ );
+ }
+
+ static function get_rotation_angle($source_filepath)
+ {
+ list($width, $height, $type) = getimagesize($source_filepath);
+ if (IMAGETYPE_JPEG != $type)
+ {
+ return null;
+ }
+
+ if (!function_exists('exif_read_data'))
+ {
+ return null;
+ }
+
+ $rotation = null;
+
+ $exif = exif_read_data($source_filepath);
+
+ if (isset($exif['Orientation']) and preg_match('/^\s*(\d)/', $exif['Orientation'], $matches))
+ {
+ $orientation = $matches[1];
+ if (in_array($orientation, array(3, 4)))
+ {
+ $rotation = 180;
+ }
+ elseif (in_array($orientation, array(5, 6)))
+ {
+ $rotation = 270;
+ }
+ elseif (in_array($orientation, array(7, 8)))
+ {
+ $rotation = 90;
+ }
+ }
+
+ return $rotation;
+ }
+
+ private function get_resize_result($destination_filepath, $width, $height, $time)
+ {
+ return array(
+ 'source' => $this->source_filepath,
+ 'destination' => $destination_filepath,
+ 'width' => $width,
+ 'height' => $height,
+ 'size' => floor(filesize($destination_filepath) / 1024).' KB',
+ 'time' => number_format((get_moment() - $time) * 1000, 2, '.', ' ').' ms',
+ 'library' => $this->library,
+ );
+ }
+
+ static function is_imagick()
+ {
+ return extension_loaded('imagick');
+ }
+
+ static function is_ext_imagick()
+ {
+ global $conf;
+
+ if (!function_exists('exec'))
+ {
+ return false;
+ }
+ @exec($conf['ext_imagick_dir'].'convert', $returnarray, $returnvalue);
+ if (!$returnvalue and !empty($returnarray[0]) and preg_match('/ImageMagick/i', $returnarray[0]))
+ {
+ return true;
+ }
+ return false;
+ }
+
+ static function is_gd()
+ {
+ return function_exists('gd_info');
+ }
+
+ function destroy()
+ {
+ if (method_exists($this->image, 'destroy'))
+ {
+ return $this->image->destroy();
+ }
+ return true;
+ }
+}
+
+// +-----------------------------------------------------------------------+
+// | Class for Imagick extension |
+// +-----------------------------------------------------------------------+
+
+class image_imagick implements imageInterface
+{
+ var $image;
+
+ function __construct($source_filepath)
+ {
+ // A bug cause that Imagick class can not be extended
+ $this->image = new Imagick($source_filepath);
+ }
+
+ function get_width()
+ {
+ return $this->image->getImageWidth();
+ }
+
+ function get_height()
+ {
+ return $this->image->getImageHeight();
+ }
+
+ function set_compression_quality($quality)
+ {
+ return $this->image->setImageCompressionQuality($quality);
+ }
+
+ function crop($width, $height, $x, $y)
+ {
+ return $this->image->cropImage($width, $height, $x, $y);
+ }
+
+ function strip()
+ {
+ return $this->image->stripImage();
+ }
+
+ function rotate($rotation)
+ {
+ $this->image->rotateImage(new ImagickPixel(), -$rotation);
+ $this->image->setImageOrientation(Imagick::ORIENTATION_TOPLEFT);
+ return true;
+ }
+
+ function resize($width, $height)
+ {
+ $this->image->setInterlaceScheme(Imagick::INTERLACE_LINE);
+ return $this->image->resizeImage($width, $height, Imagick::FILTER_LANCZOS, 0.9);
+ }
+
+ function write($destination_filepath)
+ {
+ return $this->image->writeImage($destination_filepath);
+ }
+}
+
+// +-----------------------------------------------------------------------+
+// | Class for ImageMagick external installation |
+// +-----------------------------------------------------------------------+
+
+class image_ext_imagick implements imageInterface
+{
+ var $imagickdir = '';
+ var $source_filepath = '';
+ var $image_data = array();
+ var $commands = array();
+
+ function __construct($source_filepath, $imagickdir='')
+ {
+ $this->source_filepath = $source_filepath;
+ $this->imagickdir = $imagickdir;
+
+ $command = $imagickdir."identify -verbose ".realpath($source_filepath);
+ @exec($command, $returnarray, $returnvalue);
+ if($returnvalue)
+ {
+ die("[External ImageMagick] Corrupt image");
+ }
+
+ foreach($returnarray as $value)
+ {
+ $arr = explode(':', $value, 2);
+ if (count($arr) == 2)
+ {
+ $this->image_data[trim($arr[0])] = trim($arr[1]);
+ }
+ }
+ }
+
+ function add_command($command, $params=null)
+ {
+ $this->commands[$command] = $params;
+ }
+
+ function get_width()
+ {
+ preg_match('#^(\d+)x#', $this->image_data['Geometry'], $match);
+ return isset($match[1]) ? $match[1] : false;
+ }
+
+ function get_height()
+ {
+ preg_match('#^\d+x(\d+)(?:\+|$)#', $this->image_data['Geometry'], $match);
+ return isset($match[1]) ? $match[1] : false;
+ }
+
+ function crop($width, $height, $x, $y)
+ {
+ $this->add_command('crop', $width.'x'.$height.'+'.$x.'+'.$y);
+ return true;
+ }
+
+ function strip()
+ {
+ $this->add_command('strip');
+ return true;
+ }
+
+ function rotate($rotation)
+ {
+ $this->add_command('rotate', -$rotation);
+ $this->add_command('orient', 'top-left');
+ return true;
+ }
+
+ function set_compression_quality($quality)
+ {
+ $this->add_command('quality', $quality);
+ return true;
+ }
+
+ function resize($width, $height)
+ {
+ $this->add_command('interlace', 'line');
+ $this->add_command('filter', 'Lanczos');
+ $this->add_command('resize', $width.'x'.$height.'!');
+ return true;
+ }
+
+ function write($destination_filepath)
+ {
+ $exec = $this->imagickdir.'convert';
+ $exec .= ' '.realpath($this->source_filepath);
+
+ foreach ($this->commands as $command => $params)
+ {
+ $exec .= ' -'.$command;
+ if (!empty($params))
+ {
+ $exec .= ' '.$params;
+ }
+ }
+
+ $dest = pathinfo($destination_filepath);
+ $exec .= ' '.realpath($dest['dirname']).'/'.$dest['basename'];
+ @exec($exec, $returnarray, $returnvalue);
+ return !$returnvalue;
+ }
+}
+
+// +-----------------------------------------------------------------------+
+// | Class for GD library |
+// +-----------------------------------------------------------------------+
+
+class image_gd implements imageInterface
+{
+ var $image;
+ var $quality = 95;
+
+ function __construct($source_filepath)
+ {
+ $gd_info = gd_info();
+ $extension = strtolower(get_extension($source_filepath));
+
+ if (in_array($extension, array('jpg', 'jpeg')))
+ {
+ $this->image = imagecreatefromjpeg($source_filepath);
+ }
+ else if ($extension == 'png')
+ {
+ $this->image = imagecreatefrompng($source_filepath);
+ }
+ elseif ($extension == 'gif' and $gd_info['GIF Read Support'] and $gd_info['GIF Create Support'])
+ {
+ $this->image = imagecreatefromgif($source_filepath);
+ }
+ else
+ {
+ die('[Image GD] unsupported file extension');
+ }
+ }
+
+ function get_width()
+ {
+ return imagesx($this->image);
+ }
+
+ function get_height()
+ {
+ return imagesy($this->image);
+ }
+
+ function crop($width, $height, $x, $y)
+ {
+ $dest = imagecreatetruecolor($width, $height);
+
+ imagealphablending($dest, false);
+ imagesavealpha($dest, true);
+ if (function_exists('imageantialias'))
+ {
+ imageantialias($dest, true);
+ }
+
+ $result = imagecopymerge($dest, $this->image, 0, 0, $x, $y, $width, $height, 100);
+
+ if ($result !== false)
+ {
+ imagedestroy($this->image);
+ $this->image = $dest;
+ }
+ else
+ {
+ imagedestroy($dest);
+ }
+ return $result;
+ }
+
+ function strip()
+ {
+ return true;
+ }
+
+ function rotate($rotation)
+ {
+ $dest = imagerotate($this->image, $rotation, 0);
+ imagedestroy($this->image);
+ $this->image = $dest;
+ return true;
+ }
+
+ function set_compression_quality($quality)
+ {
+ $this->quality = $quality;
+ return true;
+ }
+
+ function resize($width, $height)
+ {
+ $dest = imagecreatetruecolor($width, $height);
+
+ imagealphablending($dest, false);
+ imagesavealpha($dest, true);
+ if (function_exists('imageantialias'))
+ {
+ imageantialias($dest, true);
+ }
+
+ $result = imagecopyresampled($dest, $this->image, 0, 0, 0, 0, $width, $height, $this->get_width(), $this->get_height());
+
+ if ($result !== false)
+ {
+ imagedestroy($this->image);
+ $this->image = $dest;
+ }
+ else
+ {
+ imagedestroy($dest);
+ }
+ return $result;
+ }
+
+ function write($destination_filepath)
+ {
+ $extension = strtolower(get_extension($destination_filepath));
+
+ if ($extension == 'png')
+ {
+ imagepng($this->image, $destination_filepath);
+ }
+ elseif ($extension == 'gif')
+ {
+ imagegif($this->image, $destination_filepath);
+ }
+ else
+ {
+ imagejpeg($this->image, $destination_filepath, $this->quality);
+ }
+ }
+
+ function destroy()
+ {
+ imagedestroy($this->image);
+ }
+}
+
+?>
\ No newline at end of file diff --git a/admin/photos_add.php b/admin/photos_add.php index d0ae3050b..7760195d9 100644 --- a/admin/photos_add.php +++ b/admin/photos_add.php @@ -27,6 +27,7 @@ if( !defined("PHPWG_ROOT_PATH") ) include_once(PHPWG_ROOT_PATH.'admin/include/functions.php'); include_once(PHPWG_ROOT_PATH.'admin/include/tabsheet.class.php'); include_once(PHPWG_ROOT_PATH.'admin/include/functions_upload.inc.php'); +include_once(PHPWG_ROOT_PATH.'admin/include/image.class.php'); define( 'PHOTOS_ADD_BASE_URL', diff --git a/admin/photos_add_settings.php b/admin/photos_add_settings.php index 968b4a870..91ac9cbd9 100644 --- a/admin/photos_add_settings.php +++ b/admin/photos_add_settings.php @@ -111,7 +111,7 @@ foreach (array_keys($upload_form_config) as $field) $template->assign( array( 'F_ADD_ACTION'=> PHOTOS_ADD_BASE_URL, - 'MANAGE_HD' => is_imagick(), + 'MANAGE_HD' => (pwg_image::is_imagick() or pwg_image::is_ext_imagick()), 'values' => $form_values ) ); diff --git a/include/config_default.inc.php b/include/config_default.inc.php index b5095e63f..94eb05b01 100644 --- a/include/config_default.inc.php +++ b/include/config_default.inc.php @@ -321,6 +321,15 @@ $conf['insensitive_case_logon'] = false; // 'filename' $conf['uniqueness_mode'] = 'md5sum'; +// Library used for image resizing. Value could be 'auto', 'imagick', +// 'ext_imagick or 'gd'. If value is 'auto', library will be choosen in this +// order. If choosen library is not available, another one will be picked up. +$conf['image_library'] = 'auto'; + +// If library used is external installation of ImageMagick ('ext_imagick'), +// you can define imagemagick directory. +$conf['ext_imagick_dir'] = ''; + // +-----------------------------------------------------------------------+ // | metadata | // +-----------------------------------------------------------------------+ diff --git a/include/ws_functions.inc.php b/include/ws_functions.inc.php index c706c7f75..c60e8241b 100644 --- a/include/ws_functions.inc.php +++ b/include/ws_functions.inc.php @@ -2688,6 +2688,7 @@ function ws_images_resize($params, &$service) include_once(PHPWG_ROOT_PATH.'include/functions_picture.inc.php'); include_once(PHPWG_ROOT_PATH.'admin/include/functions_upload.inc.php'); + include_once(PHPWG_ROOT_PATH.'admin/include/image.class.php'); if (!empty($params['image_id'])) { @@ -2725,32 +2726,36 @@ SELECT id, path, tn_ext, has_high { prepare_directory(dirname($thumb_path)); - $result = trigger_event( - 'upload_thumbnail_resize', - false, - $image_path, + $img = new pwg_image($image_path, $params['library']); + + $result = $img->pwg_resize( $thumb_path, $params['maxwidth'], $params['maxheight'], $params['quality'], + $params['automatic_rotation'], true, get_boolean($params['crop']), get_boolean($params['follow_orientation']) ); + + $img->destroy(); } elseif (file_exists($hd_path)) { - $result = trigger_event( - 'upload_image_resize', - false, - $hd_path, + $img = new pwg_image($hd_path); + + $result = $img->pwg_resize( $image_path, $params['maxwidth'], $params['maxheight'], $params['quality'], + $params['automatic_rotation'], false ); + $img->destroy(); + if (!empty($image['has_high'])) { $conf['use_exif'] = false; @@ -411,6 +411,8 @@ function ws_addDefaultMethods( $arr ) 'image_id' => array('default' => null), 'image_path' => array('default' => null), 'type' => array('default' => 'thumbnail'), + 'automatic_rotation' => array('default' => $conf['upload_form_automatic_rotation']), + 'library' => array('default' => $conf['image_library']), 'maxwidth' => array('default' => null), 'maxheight' => array('default' => null), 'crop' => array('default' => null), |