CodeIgniter 圖像處理類 源代碼分析

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






















發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章