Php传图缩图,php上传图片后,自动裁剪成缩略图,宽不限高

php教程上传图片后,自动裁剪成缩略图,宽不限高

/**

* 定义 Helper_Image 类和 Helper_ImageGD 类

*

* @link http://qeephp.com/

* @copyright Copyright (c) 2006-2009 Qeeyuan Inc. {@link http://www.qeeyuan.com}

* @license New BSD License {@link http://qeephp.com/license/}

* @version $Id: image.php 1937 2009-01-05 19:09:40Z dualface $

* @package helper

*/

/**

* Helper_Image 类封装了针对图像的操作

*

* 开发者不能直接构造该类的实例,而是应该用 Helper_Image::createFromFile()

* 静态方法创建一个 Image 类的实例。

*

* 操作大图片时,请确保 php 能够分配足够的内存。

*

* @author YuLei Liao * @version $Id: image.php 1937 2009-01-05 19:09:40Z dualface $

* @package helper

*/

abstract class Helper_Image

{

/**

* 从指定文件创建 Helper_ImageGD 对象

*

* 用法:

* @code php

* $image = Helper_Image::createFromFile('1.jpg');

* $image->resize($width, $height);

* $image->saveAsJpeg('2.jpg');

* @endcode

*

* 对于上传的文件,由于其临时文件名中并没有包含扩展名。

* 因此需要采用下面的方法创建 Image 对象:

*

* @code php

* $ext = pathinfo($_FILES['postfile']['name'], PATHINFO_EXTENSION);

* $image = Image::createFromFile($_FILES['postfile']['tmp_name'], $ext);

* @endcode

*

* @param string $filename 图像文件的完整路径

* @param string $fileext 指定扩展名

*

* @return Helper_ImageGD 从文件创建的 Helper_ImageGD 对象

* @throw Q_NotImplementedException

*/

static function createFromFile($filename, $fileext)

{

$fileext = trim(strtolower($fileext), '.');

$ext2functions = array(

'jpg' => 'imagecreatefromjpeg',

'jpeg' => 'imagecreatefromjpeg',

'png' => 'imagecreatefrompng',

'gif' => 'imagecreatefromgif'

);

if (!isset($ext2functions[$fileext]))

{

throw new Q_NotImplementedException(__('imagecreateform' . $fileext));

}

$handle = call_user_func($ext2functions[$fileext], $filename);

return new Helper_ImageGD($handle);

}

/**

* 将 16 进制颜色值转换为 rgb 值

*

* 用法:

* @code php

* $color = '#369';

* list($r, $g, $b) = Helper_Image::hex2rgb($color);

* echo "red: {$r}, green: {$g}, blue: {$b}";

* @endcode

*

* @param string $color 颜色值

* @param string $default 使用无效颜色值时返回的默认颜色

*

* @return array 由 RGB 三色组成的数组

*/

static function hex2rgb($color, $default = 'ffffff')

{

$hex = trim($color, '#&Hh');

$len = strlen($hex);

if ($len == 3)

{

$hex = "{$hex[0]}{$hex[0]}{$hex[1]}{$hex[1]}{$hex[2]}{$hex[2]}";

}

elseif ($len < 6)

{

$hex = $default;

}

$dec = hexdec($hex);

return array(($dec >> 16) & 0xff, ($dec >> 8) & 0xff, $dec & 0xff);

}

}

/**

* Helper_ImageGD 类封装了一个 gd 句柄,用于对图像进行操作

*

* @author YuLei Liao * @version $Id: image.php 1937 2009-01-05 19:09:40Z dualface $

* @package helper

*/

class Helper_ImageGD

{

/**

* GD 资源句柄

*

* @var resource

*/

protected $_handle = null;

/**

* 构造函数

*

* @param resource $handle GD 资源句柄

*/

function __construct($handle)

{

$this->_handle = $handle;

}

/**

* 析构函数

*/

function __destruct()

{

$this->destroy();

}

/**

* 快速缩放图像到指定大小(质量较差)

*

* @param int $width 新的宽度

* @param int $height 新的高度

*

* @return Helper_ImageGD 返回 Helper_ImageGD 对象本身,实现连贯接口

*/

function resize($width, $height)

{

if (is_null($this->_handle)) return $this;

$dest = imagecreatetruecolor($width, $height);

imagecopyresized($dest, $this->_handle, 0, 0, 0, 0,

$width, $height,

imagesx($this->_handle), imagesy($this->_handle));

imagedestroy($this->_handle);

$this->_handle = $dest;

return $this;

}

/**

* 缩放图像到指定大小(质量较好,速度比 resize() 慢)

*

* @param int $width 新的宽度

* @param int $height 新的高度

*

* @return Helper_ImageGD 返回 Helper_ImageGD 对象本身,实现连贯接口

*/

function resampled($width, $height)

{

if (is_null($this->_handle)) return $this;

$dest = imagecreatetruecolor($width, $height);

imagecopyresampled($dest, $this->_handle, 0, 0, 0, 0,

$width, $height,

imagesx($this->_handle), imagesy($this->_handle));

imagedestroy($this->_handle);

$this->_handle = $dest;

return $this;

}

/**

* 调整图像大小,但不进行缩放操作

*

* 用法:

* @code php

* $image->resizeCanvas($width, $height, 'top-left');

* @endcode

*

* $pos 参数指定了调整图像大小时,图像内容按照什么位置对齐。

* $pos 参数的可用值有:

*

* - left: 左对齐

* - right: 右对齐

* - center: 中心对齐

* - top: 顶部对齐

* - bottom: 底部对齐

* - top-left, left-top: 左上角对齐

* - top-right, right-top: 右上角对齐

* - bottom-left, left-bottom: 左下角对齐

* - bottom-right, right-bottom: 右下角对齐

*

* 如果指定了无效的 $pos 参数,则等同于指定 center。

*

* @param int $width 新的高度

* @param int $height 新的宽度

* @param string $pos 调整时图像位置的变化

* @param string $bgcolor 空白部分的默认颜色

*

* @return Helper_ImageGD 返回 Helper_ImageGD 对象本身,实现连贯接口

*/

function resizeCanvas($width, $height, $pos = 'center', $bgcolor = '0xffffff')

{

if (is_null($this->_handle)) return $this;

$dest = imagecreatetruecolor($width, $height);

$sx = imagesx($this->_handle);

$sy = imagesy($this->_handle);

// 根据 pos 属性来决定如何定位原始图片

switch (strtolower($pos))

{

case 'left':

$ox = 0;

$oy = ($height - $sy) / 2;

break;

case 'right':

$ox = $width - $sx;

$oy = ($height - $sy) / 2;

break;

case 'top':

$ox = ($width - $sx) / 2;

$oy = 0;

break;

case 'bottom':

$ox = ($width - $sx) / 2;

$oy = $height - $sy;

break;

case 'top-left':

case 'left-top':

$ox = $oy = 0;

break;

case 'top-right':

case 'right-top':

$ox = $width - $sx;

$oy = 0;

break;

case 'bottom-left':

case 'left-bottom':

$ox = 0;

$oy = $height - $sy;

break;

case 'bottom-right':

case 'right-bottom':

$ox = $width - $sx;

$oy = $height - $sy;

break;

default:

$ox = ($width - $sx) / 2;

$oy = ($height - $sy) / 2;

}

list ($r, $g, $b) = Helper_Image::hex2rgb($bgcolor, '0xffffff');

$bgcolor = imagecolorallocate($dest, $r, $g, $b);

imagefilledrectangle($dest, 0, 0, $width, $height, $bgcolor);

imagecolordeallocate($dest, $bgcolor);

imagecopy($dest, $this->_handle, $ox, $oy, 0, 0, $sx, $sy);

imagedestroy($this->_handle);

$this->_handle = $dest;

return $this;

}

/**

* 在保持图像长宽比的情况下将图像裁减到指定大小

*

* 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;

}

/**

* 保存为 JPEG 文件

*

* @param string $filename 保存文件名

* @param int $quality 品质参数,默认为 80

*

* @return Helper_ImageGD 返回 Helper_ImageGD 对象本身,实现连贯接口

*/

function saveAsJpeg($filename, $quality = 80)

{

imagejpeg($this->_handle, $filename, $quality);

}

/**

* 保存为 PNG 文件

*

* @param string $filename 保存文件名

*

* @return Helper_ImageGD 返回 Helper_ImageGD 对象本身,实现连贯接口

*/

function saveAsPng($filename)

{

imagepng($this->_handle, $filename);

}

/**

* 保存为 GIF 文件

*

* @param string $filename 保存文件名

*

* @return Helper_ImageGD 返回 Helper_ImageGD 对象本身,实现连贯接口

*/

function saveAsGif($filename)

{

imagegif($this->_handle, $filename);

}

/**

* 销毁内存中的图像

*

* @return Helper_ImageGD 返回 Helper_ImageGD 对象本身,实现连贯接口

*/

function destroy()

{

if (!$this->_handle)

{

@imagedestroy($this->_handle);

}

$this->_handle = null;

return $this;

}

}

调用方法

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值