diff --git a/src/admin/album_edit.php b/src/admin/album_edit.php index 3791bf54..5506889e 100644 --- a/src/admin/album_edit.php +++ b/src/admin/album_edit.php @@ -160,8 +160,7 @@ else if ($dopost == 'save') { $litpicname = $pagestyle > 2 ? GetImageMapDD($iurl, $cfg_ddimg_width) : $iurl; $litimgfile = $cfg_basedir.$litpicname; } else { - if ($cfg_ddimg_full == 'Y') ImageResizeNew($imgfile, $cfg_ddimg_width, $cfg_ddimg_height, $litimgfile); - else ImageResize($imgfile, $cfg_ddimg_width, $cfg_ddimg_height, $litimgfile); + ImageResizeNew($imgfile, $cfg_ddimg_width, $cfg_ddimg_height, $litimgfile); $litpicname = $ddurl; } $imgurls .= "{dede:img ddimg='$litpicname' text='$iinfo' width='".$imginfos[0]."' height='".$imginfos[1]."'} $iurl {/dede:img}\r\n"; diff --git a/src/admin/inc/inc_archives_functions.php b/src/admin/inc/inc_archives_functions.php index c8227283..f79b7504 100644 --- a/src/admin/inc/inc_archives_functions.php +++ b/src/admin/inc/inc_archives_functions.php @@ -380,8 +380,7 @@ function GetDDImage($litpic, $picname, $isremote) } @move_uploaded_file($_FILES[$litpic]['tmp_name'], $cfg_basedir.$fullUrl); $litpic = $fullUrl; - if ($GLOBALS['cfg_ddimg_full'] == 'Y') @ImageResizeNew($cfg_basedir.$fullUrl, $cfg_ddimg_width, $cfg_ddimg_height); - else @ImageResize($cfg_basedir.$fullUrl, $cfg_ddimg_width, $cfg_ddimg_height); + @ImageResizeNew($cfg_basedir.$fullUrl, $cfg_ddimg_width, $cfg_ddimg_height); $img = $cfg_basedir.$litpic; } else { $picname = trim($picname); @@ -393,16 +392,14 @@ function GetDDImage($litpic, $picname, $isremote) } else { $litpic = $ddinfos[0]; if ($ddinfos[1] > $cfg_ddimg_width || $ddinfos[2] > $cfg_ddimg_height) { - if ($GLOBALS['cfg_ddimg_full'] == 'Y') @ImageResizeNew($cfg_basedir.$litpic, $cfg_ddimg_width, $cfg_ddimg_height); - else @ImageResize($cfg_basedir.$litpic, $cfg_ddimg_width, $cfg_ddimg_height); + @ImageResizeNew($cfg_basedir.$litpic, $cfg_ddimg_width, $cfg_ddimg_height); } } } else { if ($litpic == 'ddfirst' && !preg_match("#^http:\/\/#i", $picname)) { $oldpic = $cfg_basedir.$picname; $litpic = str_replace('.', '-ty.', $picname); - if ($GLOBALS['cfg_ddimg_full'] == 'Y') @ImageResizeNew($oldpic, $cfg_ddimg_width, $cfg_ddimg_height, $cfg_basedir.$litpic); - else @ImageResize($oldpic, $cfg_ddimg_width, $cfg_ddimg_height, $cfg_basedir.$litpic); + @ImageResizeNew($oldpic, $cfg_ddimg_width, $cfg_ddimg_height, $cfg_basedir.$litpic); if (!is_file($cfg_basedir.$litpic)) $litpic = ''; } else { $litpic = $picname; @@ -633,12 +630,11 @@ function Replace_Links(&$body, $allow_urls = array()) */ function GetImageMapDD($filename, $maxwidth) { - global $cuserLogin, $dsql, $cfg_ddimg_height, $cfg_ddimg_full; + global $cuserLogin, $dsql, $cfg_ddimg_height; $ddn = substr($filename, -3); $ddpicok = preg_replace("#\.".$ddn."$#", "-ty.".$ddn, $filename); $toFile = $GLOBALS['cfg_basedir'].$ddpicok; - if ($cfg_ddimg_full == 'Y') ImageResizeNew($GLOBALS['cfg_basedir'].$filename, $maxwidth, $cfg_ddimg_height, $toFile); - else ImageResize($GLOBALS['cfg_basedir'].$filename, $maxwidth, $cfg_ddimg_height, $toFile); + ImageResizeNew($GLOBALS['cfg_basedir'].$filename, $maxwidth, $cfg_ddimg_height, $toFile); //保存图片附件信息 $fsize = filesize($toFile); $ddpicoks = explode('/', $ddpicok); diff --git a/src/install/sql-dfdata.txt b/src/install/sql-dfdata.txt index f833e98d..33362cb5 100755 --- a/src/install/sql-dfdata.txt +++ b/src/install/sql-dfdata.txt @@ -4063,8 +4063,6 @@ INSERT INTO `#@__sysconfig` VALUES ('1','cfg_basehost','站点网址','1','strin ('127','cfg_qk_uploadlit','异步上传缩略图,空间太不稳定用户关闭此项','3','bool','Y'), ('128','cfg_login_adds','登录会员中心获积分','5','number','2'), ('129','cfg_userad_adds','会员推广获积分','5','number','10'), -('130','cfg_ddimg_full','是否使用缩略图强制大小,对背景填充','3','bool','N'), -('131','cfg_ddimg_bgcolor','缩略图空白背景填充颜色(0白,1黑)','3','number','0'), ('132','cfg_replace_num','文档关键词替换次数(0为全部替换)','7','number','1'), ('133','cfg_uplitpic_cut','是否上传缩略图后马上弹出裁剪框','3','bool','Y'), ('134','cfg_album_mark','是否使用图集水印,小图也会受影响','3','bool','N'), diff --git a/src/system/archive/archives.class.php b/src/system/archive/archives.class.php index f2a2bdae..96e3ca79 100755 --- a/src/system/archive/archives.class.php +++ b/src/system/archive/archives.class.php @@ -693,7 +693,7 @@ class Archives $this->PreNext['diy']['pre']['litpic'] = $preRow['litpic']; $this->PreNext['diy']['pre']['pubdate'] = $preRow['senddate']; $this->PreNext['pre'] = "上一篇:{$preRow['title']}"; - $this->PreNext['preimg'] = "\"{$nextRow['title']}\" "; + $this->PreNext['preimg'] = "\"{$preRow['title']}\" "; } else { $this->PreNext['pre'] = "上一篇:暂无"; $this->PreNext['preimg'] = ""; @@ -721,7 +721,7 @@ class Archives $this->PreNext['diy']['next']['litpic'] = $nextRow['litpic']; $this->PreNext['diy']['next']['pubdate'] = $nextRow['senddate']; $this->PreNext['next'] = "下一篇:{$nextRow['title']} "; - $this->PreNext['nextimg'] = "\"{$nextRow['title']}\" "; + $this->PreNext['nextimg'] = "\"{$nextRow['title']}\" "; } else { $this->PreNext['next'] = "下一篇:暂无"; $this->PreNext['nextimg'] = ""; diff --git a/src/system/helpers/image.helper.php b/src/system/helpers/image.helper.php index 43bd8845..91fd9d8e 100755 --- a/src/system/helpers/image.helper.php +++ b/src/system/helpers/image.helper.php @@ -1,5 +1,7 @@ $toW || $srcH > $toH) { - if (function_exists("imagecreateTRUEcolor")) { - @$ni = imagecreateTRUEcolor($ftoW, $ftoH); - if ($ni) { - imagecopyresampled($ni, $im, 0, 0, 0, 0, $ftoW, $ftoH, $srcW, $srcH); - } else { - $ni = imagecreate($ftoW, $ftoH); - imagecopyresized($ni, $im, 0, 0, 0, 0, $ftoW, $ftoH, $srcW, $srcH); - } - } else { - $ni = imagecreate($ftoW, $ftoH); - imagecopyresized($ni, $im, 0, 0, 0, 0, $ftoW, $ftoH, $srcW, $srcH); - } - $alpha = imagecolorallocatealpha($ni, 0, 0, 0, 127); - imagefill($ni, 0, 0, $alpha); - switch ($srcInfo[2]) { - case 1: - imagegif ($ni, $toFile); - break; - case 2: - imagejpeg($ni, $toFile, 85); - break; - case 3: - imagepng($ni, $toFile); - break; - case 6: - imagebmp($ni, $toFile); - break; - default: - return FALSE; - } - imagedestroy($ni); - } - imagedestroy($im); + try{ + $image = new ImageResize($srcFile); + $image->resizeToBestFit($toW, $toH); + $image->save($toFile); return true; - } catch (Throwable $th) { - return false; - } catch (Exception $e) { + } catch (ImageResizeException $e) { return false; } } @@ -203,118 +138,17 @@ if (!function_exists('WaterImg')) { if (!function_exists('ImageResizeNew')) { function ImageResizeNew($srcFile, $toW, $toH, $toFile = '', $issave = TRUE) { - global $cfg_photo_type, $cfg_ddimg_bgcolor; - if ($toFile == '') $toFile = $srcFile; - $info = ''; - $srcInfo = GetImageSize($srcFile, $info); - switch ($srcInfo[2]) { - case 1: - if (!$cfg_photo_type['gif']) return FALSE; - $img = imagecreatefromgif ($srcFile); - break; - case 2: - if (!$cfg_photo_type['jpeg']) return FALSE; - $img = imagecreatefromjpeg($srcFile); - break; - case 3: - if (!$cfg_photo_type['png']) return FALSE; - $img = imagecreatefrompng($srcFile); - break; - case 8: - if (!$cfg_photo_type['wbmp']) return FALSE; - $img = imagecreatefromwbmp($srcFile); - break; - case 6: - if (!$cfg_photo_type['bmp']) return FALSE; - $img = imagecreatefrombmp($srcFile); - break; - case 18: - if (!$cfg_photo_type['webp']) return FALSE; - $img = imagecreatefromwebp($srcFile); - break; - } - $width = imageSX($img); - $height = imageSY($img); - if (!$width || !$height) { - return FALSE; - } - $target_width = $toW; - $target_height = $toH; - $target_ratio = $target_width / $target_height; - $img_ratio = $width / $height; - if ($target_ratio > $img_ratio) { - $new_height = $target_height; - $new_width = $img_ratio * $target_height; - } else { - $new_height = $target_width / $img_ratio; - $new_width = $target_width; - } - if ($new_height > $target_height) { - $new_height = $target_height; - } - if ($new_width > $target_width) { - $new_height = $target_width; - } - $new_img = imagecreatetruecolor($target_width, $target_height); - $alpha = imagecolorallocatealpha($new_img, 0, 0, 0, 127); - imagefill($new_img, 0, 0, $alpha); - imagealphablending($new_img, true); - imagesavealpha($new_img, true); - if ($cfg_ddimg_bgcolor == 0) $bgcolor = ImageColorAllocate($new_img, 0xff, 0xff, 0xff); - else $bgcolor = 0; - if (!@imagefilledrectangle($new_img, 0, 0, $target_width - 1, $target_height - 1, $bgcolor)) { - return FALSE; - } - if (!@imagecopyresampled($new_img, $img, ($target_width - $new_width) / 2, ($target_height - $new_height) / 2, 0, 0, $new_width, $new_height, $width, $height)) { - return FALSE; - } - //保存为目标文件 - if ($issave) { - switch ($srcInfo[2]) { - case 1: - imagegif ($new_img, $toFile); - break; - case 2: - imagejpeg($new_img, $toFile, 100); - break; - case 3: - imagepng($new_img, $toFile); - break; - case 6: - imagebmp($new_img, $toFile); - break; - case 18: - imagewebp($new_img, $toFile); - break; - default: - return FALSE; - } - } - //不保存 - else { - switch ($srcInfo[2]) { - case 1: - imagegif ($new_img); - break; - case 2: - imagejpeg($new_img); - break; - case 3: - imagepng($new_img); - break; - case 6: - imagebmp($new_img); - break; - case 18: - imagewebp($new_img); - break; - default: - return FALSE; + try{ + $image = new ImageResize($srcFile); + $image->resizeToBestFit($toW, $toH); + if ($issave) { + $image->save($toFile); + } else { + $image->output(); } + return true; + } catch (ImageResizeException $e) { + return false; } - imagedestroy($new_img); - imagedestroy($img); - return TRUE; } } -?> \ No newline at end of file diff --git a/src/system/libraries/imageresize.class.php b/src/system/libraries/imageresize.class.php new file mode 100644 index 00000000..e9c8d58b --- /dev/null +++ b/src/system/libraries/imageresize.class.php @@ -0,0 +1,785 @@ +filters[] = $filter; + return $this; + } + + /** + * Apply filters. + * + * @param $image resource an image resource identifier + * @param $filterType filter type and default value is IMG_FILTER_NEGATE + */ + protected function applyFilter($image, $filterType = IMG_FILTER_NEGATE) + { + foreach ($this->filters as $function) { + $function($image, $filterType); + } + } + + /** + * Loads image source and its properties to the instanciated object + * + * @param string $filename + * @return ImageResize + * @throws ImageResizeException + */ + public function __construct($filename) + { + if (!defined('IMAGETYPE_WEBP')) { + define('IMAGETYPE_WEBP', 18); + } + + if (!defined('IMAGETYPE_BMP')) { + define('IMAGETYPE_BMP', 6); + } + + if ($filename === null || empty($filename) || (substr($filename, 0, 5) !== 'data:' && !is_file($filename))) { + throw new ImageResizeException('File does not exist'); + } + + $finfo = finfo_open(FILEINFO_MIME_TYPE); + $checkWebp = false; + if (strstr(finfo_file($finfo, $filename), 'image') === false) { + if (version_compare(PHP_VERSION, '7.0.0', '<=') && strstr(file_get_contents($filename), 'WEBPVP8') !== false) { + $checkWebp = true; + $this->source_type = IMAGETYPE_WEBP; + } else { + throw new ImageResizeException('Unsupported file type'); + } + } elseif(strstr(finfo_file($finfo, $filename), 'image/webp') !== false) { + $checkWebp = true; + $this->source_type = IMAGETYPE_WEBP; + } + + if (!$image_info = getimagesize($filename, $this->source_info)) { + $image_info = getimagesize($filename); + } + + if (!$checkWebp) { + if (!$image_info) { + if (strstr(finfo_file($finfo, $filename), 'image') !== false) { + throw new ImageResizeException('Unsupported image type'); + } + + throw new ImageResizeException('Could not read file'); + } + + $this->original_w = $image_info[0]; + $this->original_h = $image_info[1]; + $this->source_type = $image_info[2]; + } + + switch ($this->source_type) { + case IMAGETYPE_GIF: + $this->source_image = imagecreatefromgif($filename); + break; + + case IMAGETYPE_JPEG: + $this->source_image = $this->imageCreateJpegfromExif($filename); + + // set new width and height for image, maybe it has changed + $this->original_w = imagesx($this->source_image); + $this->original_h = imagesy($this->source_image); + + break; + + case IMAGETYPE_PNG: + $this->source_image = imagecreatefrompng($filename); + break; + + case IMAGETYPE_WEBP: + $this->source_image = imagecreatefromwebp($filename); + $this->original_w = imagesx($this->source_image); + $this->original_h = imagesy($this->source_image); + + break; + + case IMAGETYPE_BMP: + if (version_compare(PHP_VERSION, '7.2.0', '<')) { + throw new ImageResizeException('For bmp support PHP >= 7.2.0 is required'); + } + $this->source_image = imagecreatefrombmp($filename); + break; + + default: + throw new ImageResizeException('Unsupported image type'); + } + + if (!$this->source_image) { + throw new ImageResizeException('Could not load image'); + } + + finfo_close($finfo); + + return $this->resize($this->getSourceWidth(), $this->getSourceHeight()); + } + + // http://stackoverflow.com/a/28819866 + public function imageCreateJpegfromExif($filename) + { + $img = imagecreatefromjpeg($filename); + + if (!function_exists('exif_read_data') || !isset($this->source_info['APP1']) || strpos($this->source_info['APP1'], 'Exif') !== 0) { + return $img; + } + + try { + $exif = @exif_read_data($filename); + } catch (Exception $e) { + $exif = null; + } + + if (!$exif || !isset($exif['Orientation'])) { + return $img; + } + + $orientation = $exif['Orientation']; + + if ($orientation === 6 || $orientation === 5) { + $img = imagerotate($img, 270, 0); + } elseif ($orientation === 3 || $orientation === 4) { + $img = imagerotate($img, 180, 0); + } elseif ($orientation === 8 || $orientation === 7) { + $img = imagerotate($img, 90, 0); + } + + if ($orientation === 5 || $orientation === 4 || $orientation === 7) { + imageflip($img, IMG_FLIP_HORIZONTAL); + } + + return $img; + } + + /** + * Saves new image + * + * @param string $filename + * @param integer $image_type + * @param integer $quality + * @param integer $permissions + * @param boolean $exact_size + * @return static + */ + public function save($filename, $image_type = null, $quality = null, $permissions = null, $exact_size = false) + { + $image_type = $image_type ?: $this->source_type; + $quality = is_numeric($quality) ? (int) abs($quality) : null; + + switch ($image_type) { + case IMAGETYPE_GIF: + if( !empty($exact_size) && is_array($exact_size) ){ + $dest_image = imagecreatetruecolor($exact_size[0], $exact_size[1]); + } else{ + $dest_image = imagecreatetruecolor($this->getDestWidth(), $this->getDestHeight()); + } + + $background = imagecolorallocatealpha($dest_image, 255, 255, 255, 1); + imagecolortransparent($dest_image, $background); + imagefill($dest_image, 0, 0, $background); + imagesavealpha($dest_image, true); + break; + + case IMAGETYPE_JPEG: + if( !empty($exact_size) && is_array($exact_size) ){ + $dest_image = imagecreatetruecolor($exact_size[0], $exact_size[1]); + $background = imagecolorallocate($dest_image, 255, 255, 255); + imagefilledrectangle($dest_image, 0, 0, $exact_size[0], $exact_size[1], $background); + } else{ + $dest_image = imagecreatetruecolor($this->getDestWidth(), $this->getDestHeight()); + $background = imagecolorallocate($dest_image, 255, 255, 255); + imagefilledrectangle($dest_image, 0, 0, $this->getDestWidth(), $this->getDestHeight(), $background); + } + break; + + case IMAGETYPE_WEBP: + if (version_compare(PHP_VERSION, '5.5.0', '<')) { + throw new ImageResizeException('For WebP support PHP >= 5.5.0 is required'); + } + if( !empty($exact_size) && is_array($exact_size) ){ + $dest_image = imagecreatetruecolor($exact_size[0], $exact_size[1]); + $background = imagecolorallocate($dest_image, 255, 255, 255); + imagefilledrectangle($dest_image, 0, 0, $exact_size[0], $exact_size[1], $background); + } else{ + $dest_image = imagecreatetruecolor($this->getDestWidth(), $this->getDestHeight()); + $background = imagecolorallocate($dest_image, 255, 255, 255); + imagefilledrectangle($dest_image, 0, 0, $this->getDestWidth(), $this->getDestHeight(), $background); + } + + imagealphablending($dest_image, false); + imagesavealpha($dest_image, true); + + break; + + case IMAGETYPE_PNG: + if (!$this->quality_truecolor || !imageistruecolor($this->source_image)) { + if( !empty($exact_size) && is_array($exact_size) ){ + $dest_image = imagecreate($exact_size[0], $exact_size[1]); + } else{ + $dest_image = imagecreate($this->getDestWidth(), $this->getDestHeight()); + } + } else { + if( !empty($exact_size) && is_array($exact_size) ){ + $dest_image = imagecreatetruecolor($exact_size[0], $exact_size[1]); + } else{ + $dest_image = imagecreatetruecolor($this->getDestWidth(), $this->getDestHeight()); + } + } + + imagealphablending($dest_image, false); + imagesavealpha($dest_image, true); + + $background = imagecolorallocatealpha($dest_image, 255, 255, 255, 127); + imagecolortransparent($dest_image, $background); + imagefill($dest_image, 0, 0, $background); + break; + + case IMAGETYPE_BMP: + if (version_compare(PHP_VERSION, '7.2.0', '<')) { + throw new ImageResizeException('For WebP support PHP >= 7.2.0 is required'); + } + + if(!empty($exact_size) && is_array($exact_size)) { + $dest_image = imagecreatetruecolor($exact_size[0], $exact_size[1]); + $background = imagecolorallocate($dest_image, 255, 255, 255); + imagefilledrectangle($dest_image, 0, 0, $exact_size[0], $exact_size[1], $background); + } else { + $dest_image = imagecreatetruecolor($this->getDestWidth(), $this->getDestHeight()); + $background = imagecolorallocate($dest_image, 255, 255, 255); + imagefilledrectangle($dest_image, 0, 0, $this->getDestWidth(), $this->getDestHeight(), $background); + } + break; + } + + imageinterlace($dest_image, $this->interlace); + + if ($this->gamma_correct) { + imagegammacorrect($this->source_image, 2.2, 1.0); + } + + if( !empty($exact_size) && is_array($exact_size) ) { + if ($this->getSourceHeight() < $this->getSourceWidth()) { + $this->dest_x = 0; + $this->dest_y = ($exact_size[1] - $this->getDestHeight()) / 2; + } + if ($this->getSourceHeight() > $this->getSourceWidth()) { + $this->dest_x = ($exact_size[0] - $this->getDestWidth()) / 2; + $this->dest_y = 0; + } + } + + imagecopyresampled( + $dest_image, + $this->source_image, + $this->dest_x, + $this->dest_y, + $this->source_x, + $this->source_y, + $this->getDestWidth(), + $this->getDestHeight(), + $this->source_w, + $this->source_h + ); + + if ($this->gamma_correct) { + imagegammacorrect($dest_image, 1.0, 2.2); + } + + + $this->applyFilter($dest_image); + + switch ($image_type) { + case IMAGETYPE_GIF: + imagegif($dest_image, $filename); + break; + + case IMAGETYPE_JPEG: + if ($quality === null || $quality > 100) { + $quality = $this->quality_jpg; + } + + imagejpeg($dest_image, $filename, $quality); + break; + + case IMAGETYPE_WEBP: + if (version_compare(PHP_VERSION, '5.5.0', '<')) { + throw new ImageResizeException('For WebP support PHP >= 5.5.0 is required'); + } + if ($quality === null) { + $quality = $this->quality_webp; + } + + imagewebp($dest_image, $filename, $quality); + break; + + case IMAGETYPE_PNG: + if ($quality === null || $quality > 9) { + $quality = $this->quality_png; + } + + imagepng($dest_image, $filename, $quality); + break; + + case IMAGETYPE_BMP: + imagebmp($dest_image, $filename, $quality); + break; + } + + if ($permissions) { + chmod($filename, $permissions); + } + + imagedestroy($dest_image); + + return $this; + } + + /** + * Convert the image to string + * + * @param int $image_type + * @param int $quality + * @return string + */ + public function getImageAsString($image_type = null, $quality = null) + { + $string_temp = tempnam(sys_get_temp_dir(), ''); + + $this->save($string_temp, $image_type, $quality); + + $string = file_get_contents($string_temp); + + unlink($string_temp); + + return $string; + } + + /** + * Convert the image to string with the current settings + * + * @return string + */ + public function __toString() + { + return $this->getImageAsString(); + } + + /** + * Outputs image to browser + * @param string $image_type + * @param integer $quality + */ + public function output($image_type = null, $quality = null) + { + $image_type = $image_type ?: $this->source_type; + + header('Content-Type: ' . image_type_to_mime_type($image_type)); + + $this->save(null, $image_type, $quality); + } + + /** + * Resizes image according to the given short side (short side proportional) + * + * @param integer $max_short + * @param boolean $allow_enlarge + * @return static + */ + public function resizeToShortSide($max_short, $allow_enlarge = false) + { + if ($this->getSourceHeight() < $this->getSourceWidth()) { + $ratio = $max_short / $this->getSourceHeight(); + $long = (int) ($this->getSourceWidth() * $ratio); + + $this->resize($long, $max_short, $allow_enlarge); + } else { + $ratio = $max_short / $this->getSourceWidth(); + $long = (int) ($this->getSourceHeight() * $ratio); + + $this->resize($max_short, $long, $allow_enlarge); + } + + return $this; + } + + /** + * Resizes image according to the given long side (short side proportional) + * + * @param integer $max_long + * @param boolean $allow_enlarge + * @return static + */ + public function resizeToLongSide($max_long, $allow_enlarge = false) + { + if ($this->getSourceHeight() > $this->getSourceWidth()) { + $ratio = $max_long / $this->getSourceHeight(); + $short = (int) ($this->getSourceWidth() * $ratio); + + $this->resize($short, $max_long, $allow_enlarge); + } else { + $ratio = $max_long / $this->getSourceWidth(); + $short = (int) ($this->getSourceHeight() * $ratio); + + $this->resize($max_long, $short, $allow_enlarge); + } + + return $this; + } + + /** + * Resizes image according to the given height (width proportional) + * + * @param integer $height + * @param boolean $allow_enlarge + * @return static + */ + public function resizeToHeight($height, $allow_enlarge = false) + { + $ratio = $height / $this->getSourceHeight(); + $width = (int) ($this->getSourceWidth() * $ratio); + + $this->resize($width, $height, $allow_enlarge); + + return $this; + } + + /** + * Resizes image according to the given width (height proportional) + * + * @param integer $width + * @param boolean $allow_enlarge + * @return static + */ + public function resizeToWidth($width, $allow_enlarge = false) + { + $ratio = $width / $this->getSourceWidth(); + $height = (int) ($this->getSourceHeight() * $ratio); + + $this->resize($width, $height, $allow_enlarge); + + return $this; + } + + /** + * Resizes image to best fit inside the given dimensions + * + * @param integer $max_width + * @param integer $max_height + * @param boolean $allow_enlarge + * @return static + */ + public function resizeToBestFit($max_width, $max_height, $allow_enlarge = false) + { + if ($this->getSourceWidth() <= $max_width && $this->getSourceHeight() <= $max_height && $allow_enlarge === false) { + return $this; + } + + $ratio = $this->getSourceHeight() / $this->getSourceWidth(); + $width = $max_width; + $height = (int) ($width * $ratio); + + if ($height > $max_height) { + $height = $max_height; + $width = (int) ($height / $ratio); + } + + return $this->resize($width, $height, $allow_enlarge); + } + + /** + * Resizes image according to given scale (proportionally) + * + * @param integer|float $scale + * @return static + */ + public function scale($scale) + { + $width = (int) ($this->getSourceWidth() * $scale / 100); + $height = (int) ($this->getSourceHeight() * $scale / 100); + + $this->resize($width, $height, true); + + return $this; + } + + /** + * Resizes image according to the given width and height + * + * @param integer $width + * @param integer $height + * @param boolean $allow_enlarge + * @return static + */ + public function resize($width, $height, $allow_enlarge = false) + { + if (!$allow_enlarge) { + // if the user hasn't explicitly allowed enlarging, + // but either of the dimensions are larger then the original, + // then just use original dimensions - this logic may need rethinking + + if ($width > $this->getSourceWidth() || $height > $this->getSourceHeight()) { + $width = $this->getSourceWidth(); + $height = $this->getSourceHeight(); + } + } + + $this->source_x = 0; + $this->source_y = 0; + + $this->dest_w = $width; + $this->dest_h = $height; + + $this->source_w = $this->getSourceWidth(); + $this->source_h = $this->getSourceHeight(); + + return $this; + } + + /** + * Crops image according to the given width, height and crop position + * + * @param integer $width + * @param integer $height + * @param boolean $allow_enlarge + * @param integer $position + * @return static + */ + public function crop($width, $height, $allow_enlarge = false, $position = self::CROPCENTER) + { + if (!$allow_enlarge) { + // this logic is slightly different to resize(), + // it will only reset dimensions to the original + // if that particular dimenstion is larger + + if ($width > $this->getSourceWidth()) { + $width = $this->getSourceWidth(); + } + + if ($height > $this->getSourceHeight()) { + $height = $this->getSourceHeight(); + } + } + + $ratio_source = $this->getSourceWidth() / $this->getSourceHeight(); + $ratio_dest = $width / $height; + + if ($ratio_dest < $ratio_source) { + $this->resizeToHeight($height, $allow_enlarge); + + $excess_width = (int) (($this->getDestWidth() - $width) * $this->getSourceWidth() / $this->getDestWidth()); + + $this->source_w = $this->getSourceWidth() - $excess_width; + $this->source_x = $this->getCropPosition($excess_width, $position); + + $this->dest_w = $width; + } else { + $this->resizeToWidth($width, $allow_enlarge); + + $excess_height = (int) (($this->getDestHeight() - $height) * $this->getSourceHeight() / $this->getDestHeight()); + + $this->source_h = $this->getSourceHeight() - $excess_height; + $this->source_y = $this->getCropPosition($excess_height, $position); + + $this->dest_h = $height; + } + + return $this; + } + + /** + * Crops image according to the given width, height, x and y + * + * @param integer $width + * @param integer $height + * @param integer $x + * @param integer $y + * @return static + */ + public function freecrop($width, $height, $x = false, $y = false) + { + if ($x === false || $y === false) { + return $this->crop($width, $height); + } + $this->source_x = $x; + $this->source_y = $y; + if ($width > $this->getSourceWidth() - $x) { + $this->source_w = $this->getSourceWidth() - $x; + } else { + $this->source_w = $width; + } + + if ($height > $this->getSourceHeight() - $y) { + $this->source_h = $this->getSourceHeight() - $y; + } else { + $this->source_h = $height; + } + + $this->dest_w = $width; + $this->dest_h = $height; + + return $this; + } + + /** + * Gets source width + * + * @return integer + */ + public function getSourceWidth() + { + return $this->original_w; + } + + /** + * Gets source height + * + * @return integer + */ + public function getSourceHeight() + { + return $this->original_h; + } + + /** + * Gets width of the destination image + * + * @return integer + */ + public function getDestWidth() + { + return $this->dest_w; + } + + /** + * Gets height of the destination image + * @return integer + */ + public function getDestHeight() + { + return $this->dest_h; + } + + /** + * Gets crop position (X or Y) according to the given position + * + * @param integer $expectedSize + * @param integer $position + * @return integer + */ + protected function getCropPosition($expectedSize, $position = self::CROPCENTER) + { + $size = 0; + switch ($position) { + case self::CROPBOTTOM: + case self::CROPRIGHT: + $size = $expectedSize; + break; + case self::CROPCENTER: + case self::CROPCENTRE: + $size = $expectedSize / 2; + break; + case self::CROPTOPCENTER: + $size = $expectedSize / 4; + break; + } + return (int) $size; + } + + /** + * Enable or not the gamma color correction on the image, enabled by default + * + * @param bool $enable + * @return static + */ + public function gamma($enable = false) + { + $this->gamma_correct = $enable; + + return $this; + } +} \ No newline at end of file