CodeIgniter 的图像处理类可以使你完成以下的操作:
- 调整图像大小:$this->image_lib->resize()
- 创建缩略图:
- 图像裁剪:$this->image_lib->crop()
- 图像旋转:$this->image_lib->rotate()
- 添加图像水印:$this->image_lib_watermark()
可以很好的支持三个主流的图像库:GD/GD2, NetPBM, 和 ImageMagick。
一、从图像处理类的构造函数分析,构造函数调用成员方法Initialize()初始化配置参数:
public function __construct($props = array())
{
if (count($props) > 0)
{
$this->initialize($props);
}
log_message('debug', "Image Lib Class Initialized");
}
二、是Initialize()函数过程如下:
第一步:将数组元素转变成类变量
if (count($props) > 0)
{
foreach ($props as $key => $val)
{
$this->$key = $val;
}
}
第二步:判断原始图像是否存在,如果不存在返回FALSE:
if ($this->source_image == '')
{
$this->set_error('imglib_source_image_required');
return FALSE;
}
第三步:判断getimagesize()函数是否存在,用该函数获取图像的属性,宽度、高度、图像类型标记,并将图像库变量转换为小写:
if ( ! function_exists('getimagesize'))
{
$this->set_error('imglib_gd_required_for_props');
return FALSE;
}
$this->image_library = strtolower($this->image_library);
第四步:设置图像的完整路径,利用realpath()函数,并利用str_replace()函数将路径中的\替换成/
if (function_exists('realpath') AND @realpath($this->source_image) !== FALSE)
{
$full_source_path = str_replace("\\", "/", realpath($this->source_image));
}
else
{
$full_source_path = $this->source_image;
}
$x = explode('/', $full_source_path);
$this->source_image = end($x);
$this->source_folder = str_replace($this->source_image, '', $full_source_path);
第五步:通过调用get_image_properties()成员函数获取图像的属性:
if ( ! $this->get_image_properties($this->source_folder.$this->source_image))
{
return FALSE;
}
第六步:如果new_image参数被设置,说明要复制图像或者更新原始图像
if ($this->new_image == '')
{
$this->dest_image = $this->source_image;
$this->dest_folder = $this->source_folder;
}
else
{
if (strpos($this->new_image, '/') === FALSE AND strpos($this->new_image, '\\') === FALSE)
{
$this->dest_folder = $this->source_folder;
$this->dest_image = $this->new_image;
}
else
{
if (function_exists('realpath') AND @realpath($this->new_image) !== FALSE)
{
$full_dest_path = str_replace("\\", "/", realpath($this->new_image));
}
else
{
$full_dest_path = $this->new_image;
}
// Is there a file name?
if ( ! preg_match("#\.(jpg|jpeg|gif|png)$#i", $full_dest_path))
{
$this->dest_folder = $full_dest_path.'/';
$this->dest_image = $this->source_image;
}
else
{
$x = explode('/', $full_dest_path);
$this->dest_image = end($x);
$this->dest_folder = str_replace($this->dest_image, '', $full_dest_path);
}
}
}
第八步:判断create_thumb是否假,如果为假,预览图像的标示被设置为空:
if ($this->create_thumb === FALSE OR $this->thumb_marker == '')
{
$this->thumb_marker = '';
}
第九步:生成原始图像的路径全名和目标文件的路径全名:
$xp = $this->explode_name($this->dest_image);
$filename = $xp['name'];
$file_ext = $xp['ext'];
$this->full_src_path = $this->source_folder.$this->source_image;
$this->full_dst_path = $this->dest_folder.$filename.$this->thumb_marker.$file_ext;
第十步:判断maintain_ratio(指定是否在缩放或使用硬值的时候使图像保持原始的纵横比例)是否为真,如果为真调用image_reproportion()
if ($this->maintain_ratio === TRUE && ($this->width != '' AND $this->height != ''))
{
$this->image_reproportion();
}
第十一步:如果没有设置目标图像的宽度和高度则使用原始图像的高度和宽度
if ($this->width == '')
$this->width = $this->orig_width;
if ($this->height == '')
$this->height = $this->orig_height;
第十二步:设置图像的质量:
$this->quality = trim(str_replace("%", "", $this->quality));
if ($this->quality == '' OR $this->quality == 0 OR ! is_numeric($this->quality))
$this->quality = 90;
第十四步:设置裁剪的x、y坐标:
$this->x_axis = ($this->x_axis == '' OR ! is_numeric($this->x_axis)) ? 0 : $this->x_axis;
$this->y_axis = ($this->y_axis == '' OR ! is_numeric($this->y_axis)) ? 0 : $this->y_axis;
第十五步:设置一些水印的属性:
if ($this->wm_shadow_color != '')
{
if (strlen($this->wm_shadow_color) == 6)
{
$this->wm_shadow_color = '#'.$this->wm_shadow_color;
}
}
if ($this->wm_overlay_path != '')
{
$this->wm_overlay_path = str_replace("\\", "/", realpath($this->wm_overlay_path));
}
if ($this->wm_shadow_color != '')
{
$this->wm_use_drop_shadow = TRUE;
}
if ($this->wm_font_path != '')
{
$this->wm_use_truetype = TRUE;
}
三、调整图像大小:$this->image_lib->resize()、图像裁剪:$this->image_lib->crop()都是调用成员函数image_process_gd(),
resize():
function resize()
{
$protocol = 'image_process_'.$this->image_library;
if (preg_match('/gd2$/i', $protocol))
{
$protocol = 'image_process_gd';
}
return $this->$protocol('resize');
}
crop():
function crop()
{
$protocol = 'image_process_'.$this->image_library;
if (preg_match('/gd2$/i', $protocol))
{
$protocol = 'image_process_gd';
}
return $this->$protocol('crop');
}
image_process_gd():该函数
①先判断dynamic_output是否为FALSE,如果是FALSE,且设置的宽度、高度和原始图像的高度、宽度一样,则只对原始图像赋值到目标路径
②然后判断变量$action,如果为crop,则把原始图像高度、宽度设置为将要裁剪的高度和宽度;如果不为crop,则为resize,则把$x_axis和$y_axis设置为0
③调用image_create_gd()创建图像,image_create_gd()根据$this->image_type分别调用imagecreatefromgif()、imagecreatefromjpeg()、imagecreatefrompng()创建图像
④如果支持gd2,则调用imagecreatetruecolor()和imagecopyresampled(),如果不支持则调用imagecreate()和imagecopyresized(),然后如果图像类型为png,可以保持图像的透明度imagealphablending()和imagesavealpha()
⑤如果变量$dynamic_output(动态输出)为真,则显示图像,如果为FALSE则调用image_save_gd()输出图像
⑥最后销毁图像,并调用chmod改变文件模式
function image_process_gd($action = 'resize')
{
$v2_override = FALSE;
// If the target width/height match the source, AND if the new file name is not equal to the old file name
// we'll simply make a copy of the original with the new name... assuming dynamic rendering is off.
if ($this->dynamic_output === FALSE)
{
if ($this->orig_width == $this->width AND $this->orig_height == $this->height)
{
if ($this->source_image != $this->new_image)
{
if (@copy($this->full_src_path, $this->full_dst_path))
{
@chmod($this->full_dst_path, FILE_WRITE_MODE);
}
}
return TRUE;
}
}
// Let's set up our values based on the action
if ($action == 'crop')
{
// Reassign the source width/height if cropping
$this->orig_width = $this->width;
$this->orig_height = $this->height;
// GD 2.0 has a cropping bug so we'll test for it
if ($this->gd_version() !== FALSE)
{
$gd_version = str_replace('0', '', $this->gd_version());
$v2_override = ($gd_version == 2) ? TRUE : FALSE;
}
}
else
{
// If resizing the x/y axis must be zero
$this->x_axis = 0;
$this->y_axis = 0;
}
// Create the image handle
if ( ! ($src_img = $this->image_create_gd()))
{
return FALSE;
}
// Create The Image
//
// old conditional which users report cause problems with shared GD libs who report themselves as "2.0 or greater"
// it appears that this is no longer the issue that it was in 2004, so we've removed it, retaining it in the comment
// below should that ever prove inaccurate.
//
// if ($this->image_library == 'gd2' AND function_exists('imagecreatetruecolor') AND $v2_override == FALSE)
if ($this->image_library == 'gd2' AND function_exists('imagecreatetruecolor'))
{
$create = 'imagecreatetruecolor';
$copy = 'imagecopyresampled';
}
else
{
$create = 'imagecreate';
$copy = 'imagecopyresized';
}
$dst_img = $create($this->width, $this->height);
if ($this->image_type == 3) // png we can actually preserve transparency
{
imagealphablending($dst_img, FALSE);
imagesavealpha($dst_img, TRUE);
}
$copy($dst_img, $src_img, 0, 0, $this->x_axis , $this->y_axis, $this->width, $this->height, $this->orig_width, $this->orig_height);
// Show the image
if ($this->dynamic_output == TRUE)
{
$this->image_display_gd($dst_img);
}
else
{
// Or save it
if ( ! $this->image_save_gd($dst_img))
{
return FALSE;
}
}
// Kill the file handles
imagedestroy($dst_img);
imagedestroy($src_img);
// Set the file to 777
@chmod($this->full_dst_path, FILE_WRITE_MODE);
return TRUE;
}
四、图像水印watemark(),该函数判断水印处理类型$wm_type,如果为overlay,则调用overlay_watermark(),否则调用text_watemark(),默认为text
function watermark()
{
if ($this->wm_type == 'overlay')
{
return $this->overlay_watermark();
}
else
{
return $this->text_watermark();
}
}
overlay_watermark():