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():