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






















评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值