예제 #1
0
 /**
  * 在保持图像长宽比的情况下将图像裁减到指定大小
  *
  * crop() 在缩放图像时,可以保持图像的长宽比,从而保证图像不会拉高或压扁。
  *
  * crop() 默认情况下会按照 $width 和 $height 参数计算出最大缩放比例,
  * 保持裁减后的图像能够最大程度的充满图片。
  *
  * 例如源图的大小是 800 x 600,而指定的 $width 和 $height 是 200 和 100。
  * 那么源图会被首先缩小为 200 x 150 尺寸,然后裁减掉多余的 50 像素高度。
  *
  * 用法:
  * @code php
  * $image->crop($width, $height);
  * @endcode
  *
  * 如果希望最终生成图片始终包含完整图像内容,那么应该指定 $options 参数。
  * 该参数可用值有:
  *
  * -   fullimage: 是否保持完整图像
  * -   pos: 缩放时的对齐方式
  * -   bgcolor: 缩放时多余部分的背景色
  * -   enlarge: 是否允许放大
  * -   reduce: 是否允许缩小
  *
  * 其中 $options['pos'] 参数的可用值有:
  *
  * -   left: 左对齐
  * -   right: 右对齐
  * -   center: 中心对齐
  * -   top: 顶部对齐
  * -   bottom: 底部对齐
  * -   top-left, left-top: 左上角对齐
  * -   top-right, right-top: 右上角对齐
  * -   bottom-left, left-bottom: 左下角对齐
  * -   bottom-right, right-bottom: 右下角对齐
  *
  * 如果指定了无效的 $pos 参数,则等同于指定 center。
  *
  * $options 中的每一个选项都可以单独指定,例如在允许裁减的情况下将图像放到新图片的右下角。
  *
  * @code php
  * $image->crop($width, $height, array('pos' => 'right-bottom'));
  * @endcode
  *
  * @param int $width 新的宽度
  * @param int $height 新的高度
  * @param array $options 裁减选项
  *
  * @return Helper_ImageGD 返回 Helper_ImageGD 对象本身,实现连贯接口
  */
 function crop($width, $height, $options = array())
 {
     if (is_null($this->_handle)) {
         return $this;
     }
     $default_options = array('fullimage' => false, 'pos' => 'center', 'bgcolor' => '0xfff', 'enlarge' => false, 'reduce' => true);
     $options = array_merge($default_options, $options);
     // 创建目标图像
     $dest = imagecreatetruecolor($width, $height);
     // 填充背景色
     list($r, $g, $b) = Helper_Image::hex2rgb($options['bgcolor'], '0xffffff');
     $bgcolor = imagecolorallocate($dest, $r, $g, $b);
     imagefilledrectangle($dest, 0, 0, $width, $height, $bgcolor);
     imagecolordeallocate($dest, $bgcolor);
     // 根据源图计算长宽比
     $full_w = imagesx($this->_handle);
     $full_h = imagesy($this->_handle);
     $ratio_w = doubleval($width) / doubleval($full_w);
     $ratio_h = doubleval($height) / doubleval($full_h);
     if ($options['fullimage']) {
         // 如果要保持完整图像,则选择最小的比率
         $ratio = $ratio_w < $ratio_h ? $ratio_w : $ratio_h;
     } else {
         // 否则选择最大的比率
         $ratio = $ratio_w > $ratio_h ? $ratio_w : $ratio_h;
     }
     if (!$options['enlarge'] && $ratio > 1) {
         $ratio = 1;
     }
     if (!$options['reduce'] && $ratio < 1) {
         $ratio = 1;
     }
     // 计算目标区域的宽高、位置
     $dst_w = $full_w * $ratio;
     $dst_h = $full_h * $ratio;
     // 根据 pos 属性来决定如何定位
     switch (strtolower($options['pos'])) {
         case 'left':
             $dst_x = 0;
             $dst_y = ($height - $dst_h) / 2;
             break;
         case 'right':
             $dst_x = $width - $dst_w;
             $dst_y = ($height - $dst_h) / 2;
             break;
         case 'top':
             $dst_x = ($width - $dst_w) / 2;
             $dst_y = 0;
             break;
         case 'bottom':
             $dst_x = ($width - $dst_w) / 2;
             $dst_y = $height - $dst_h;
             break;
         case 'top-left':
         case 'left-top':
             $dst_x = $dst_y = 0;
             break;
         case 'top-right':
         case 'right-top':
             $dst_x = $width - $dst_w;
             $dst_y = 0;
             break;
         case 'bottom-left':
         case 'left-bottom':
             $dst_x = 0;
             $dst_y = $height - $dst_h;
             break;
         case 'bottom-right':
         case 'right-bottom':
             $dst_x = $width - $dst_w;
             $dst_y = $height - $dst_h;
             break;
         case 'center':
         default:
             $dst_x = ($width - $dst_w) / 2;
             $dst_y = ($height - $dst_h) / 2;
     }
     imagecopyresampled($dest, $this->_handle, $dst_x, $dst_y, 0, 0, $dst_w, $dst_h, $full_w, $full_h);
     imagedestroy($this->_handle);
     $this->_handle = $dest;
     return $this;
 }
예제 #2
0
파일: image.php 프로젝트: fchaose/qeephp
 /**
  * 在保持图像长宽比的情况下将图像裁减到指定大小
  *
  * @param int $width
  * @param int $height
  * @param boolean $highQuality
  * @param array $nocut
  */
 function crop($width, $height, $highQuality = true, $nocut = null)
 {
     if (is_null($this->_handle)) {
         return;
     }
     $dest = imagecreatetruecolor($width, $height);
     $sx = imagesx($this->_handle);
     $sy = imagesy($this->_handle);
     $ratio = doubleval($width) / doubleval($sx);
     if (!is_array($nocut)) {
         if ($nocut) {
             $nocut = array('enabled' => true, 'pos' => 'center', 'bgcolor' => '0xffffff');
         } else {
             $nocut = array('enabled' => false);
         }
     } else {
         $nocut['enabled'] = isset($nocut['enabled']) ? $nocut['enabled'] : true;
         $nocut['pos'] = isset($nocut['pos']) ? $nocut['pos'] : 'center';
         $nocut['bgcolor'] = isset($nocut['bgcolor']) ? $nocut['bgcolor'] : '0xffffff';
     }
     if ($nocut['enabled']) {
         // 求缩放后的最大宽度和高度
         if ($sy * $ratio > $height) {
             $ratio = doubleval($height) / doubleval($sy);
         }
         $dx = $sx * $ratio;
         $dy = $sy * $ratio;
         // 根据 pos 属性来决定如何定位原始图片
         switch (strtolower($nocut['pos'])) {
             case 'left':
                 $ox = 0;
                 $oy = ($height - $sy * $ratio) / 2;
                 break;
             case 'right':
                 $ox = $width - $sx * $ratio;
                 $oy = ($height - $sy * $ratio) / 2;
                 break;
             case 'top':
                 $ox = ($width - $sx * $ratio) / 2;
                 $oy = 0;
                 break;
             case 'bottom':
                 $ox = ($width - $sx * $ratio) / 2;
                 $oy = $height - $sy * $ratio;
                 break;
             case 'top-left':
                 $ox = $oy = 0;
                 break;
             case 'top-right':
                 $ox = $width - $sx * $ratio;
                 $oy = 0;
                 break;
             case 'bottom-left':
                 $ox = 0;
                 $oy = $height - $sy * $ratio;
                 break;
             case 'bottom-right':
                 $ox = $width - $sx * $ratio;
                 $oy = $height - $sy * $ratio;
                 break;
             default:
                 $ox = ($width - $sx * $ratio) / 2;
                 $oy = ($height - $sy * $ratio) / 2;
         }
         list($r, $g, $b) = Helper_Image::hex2rgb($nocut['bgcolor'], '0xffffff');
         $bgcolor = imagecolorallocate($dest, $r, $g, $b);
         imagefilledrectangle($dest, 0, 0, $width, $height, $bgcolor);
         imagecolordeallocate($dest, $bgcolor);
         $args = array($dest, $this->_handle, $ox, $oy, 0, 0, $dx, $dy, $sx, $sy);
     } else {
         // 允许图像溢出
         if ($sy * $ratio < $height) {
             // 当按照比例缩放后的图像高度小于要求的高度时,只有放弃原始图像右边的部分内容
             $ratio = doubleval($sy) / doubleval($height);
             $sx = $width * $ratio;
         } elseif ($sy * $ratio > $height) {
             // 当按照比例缩放后的图像高度大于要求的高度时,只有放弃原始图像底部的部分内容
             $ratio = doubleval($sx) / doubleval($width);
             $sy = $height * $ratio;
         }
         $args = array($dest, $this->_handle, 0, 0, 0, 0, $width, $height, $sx, $sy);
     }
     if ($highQuality) {
         call_user_func_array('imagecopyresampled', $args);
     } else {
         call_user_func_array('imagecopyresized', $args);
     }
     imagedestroy($this->_handle);
     $this->_handle = $dest;
 }