[PHP] Codeigniter 縮圖處理程式,等比例切圖

by Mesak

Codeigniter 內建的 圖片操作類 其中的 resize 處理函式 如果設定等比例的為 FALSE,那圖片就會變成強制指定 SIZE 的圖片,這時候就會扭曲變形

例圖

如果預設將 maintain_ratio 設定為 FALSE 的話,就會出現右圖的狀態

如果要設定等比例切圖變成左邊縮圖的狀態的話,至少要把圖片的最小邊變成指定的邊寬,然後縮圖在設定切圖

<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class MY_Image_lib extends CI_Image_lib{
	public function __construct($props = array())
	{
		if (count($props) > 0)
		{
			$this->initialize($props);
		}
		log_message('debug', "Image Lib Class Initialized");
	}
	public function get_info()
	{
		$result = array(
			'width'=>$this->width,
			'height'=>$this->height,
			'path'=> str_replace( str_replace('\\','/',FCPATH) , '', dirname($this->full_dst_path) ),
			'fullpath'=> $this->full_dst_path,
			'filename'=> $this->dest_image
		);
		$result['filepath'] = $result['path'] .'/' .$result['filename'];
		$result['url'] = base_url( $result['filepath'] );
		return $result;
	}
	public function resize()
	{
		$protocol = 'image_process_'.$this->image_library;
		if (preg_match('/gd2$/i', $protocol))
		{
			$protocol = ($this->maintain_ratio ) ? 'image_process_gd' : 'my_image_process_gd';
		}
		return $this->$protocol('resize');
	}
	function my_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;
			}
		}
		$crop_w = $this->width;
		$crop_h = $this->height;
		$type_origin = $this->orig_height / $this->orig_width;
		if( $type_origin == 1 ){
			$type_origin = 'square';
		}else if( $type_origin < 1 ){
			$type_origin = 'w_rectangle';
		}else{
			$type_origin = 'h_rectangle';
		}
		$type_crop = $crop_h / $crop_w;
		if( $type_crop == 1 ){
			$type_crop = 'square';
		}else if( $type_crop < 1 ){
			$type_crop = 'w_rectangle';
		}else{
			$type_crop = 'h_rectangle';
		}
		$type_porp_w = round($crop_w / $this->orig_width,2);
		$type_porp_h = round($crop_h / $this->orig_height,2);

		$type_pw_w = ceil($this->orig_width * $type_porp_w);
		$type_pw_h = ceil($this->orig_height * $type_porp_w);

		$type_ph_w = ceil($this->orig_width * $type_porp_h);
		$type_ph_h = ceil($this->orig_height * $type_porp_h);
		
		if( $crop_h < $type_pw_h )
		{
			$this->width = $type_pw_w;
			$this->height= $type_pw_h;
		}else{
			$this->width = $type_ph_w;
			$this->height= $type_ph_h;
		}

		if ( ! ($src_img = $this->image_create_gd()))
		{
			return FALSE;
		}
		if ($this->image_library == 'gd2' AND function_exists('imagecreatetruecolor'))
		{
			$create	= 'imagecreatetruecolor';
			$copy	= 'imagecopyresampled';
		}
		else
		{
			$create	= 'imagecreate';
			$copy	= 'imagecopyresized';
		}
		
		$rst_img = $create($this->width, $this->height);
		if ($this->image_type == 3) // png we can actually preserve transparency
		{
			imagealphablending($rst_img, FALSE);
			imagesavealpha($rst_img, TRUE);
		}

		$copy($rst_img, $src_img, 0, 0, 0, 0, $this->width, $this->height, $this->orig_width, $this->orig_height);

		$dst_img = $create($crop_w, $crop_h);
		if ($this->image_type == 3) // png we can actually preserve transparency
		{
			imagealphablending($dst_img, FALSE);
			imagesavealpha($dst_img, TRUE);
		}

		if( $type_crop == 'square')
		{
			$crop_x = ( $type_origin == 'w_rectangle' ) ? ceil( ($this->width - $this->height) / 2 ) : 0 ;
			$crop_y = ( $type_origin == 'h_rectangle' ) ? ceil( ($this->height - $this->width) / 2 ) : 0 ;
		}else{
			$crop_x = ( $type_origin == 'w_rectangle' ) ? ceil( ($this->width - $crop_w) / 2 ) : 0 ;
			$crop_y = ( $type_origin == 'h_rectangle' ) ? ceil( ($this->height - $crop_h) / 2 ) : 0 ;
		}
		
		$copy($dst_img, $rst_img, 0, 0, $crop_x, $crop_y, $crop_w, $crop_h, $crop_w, $crop_h);
		$this->width = $crop_w;
		$this->height = $crop_h;
		
		//  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($rst_img);
		imagedestroy($dst_img);
		imagedestroy($src_img);
		// Set the file to 777
		@chmod($this->full_dst_path, FILE_WRITE_MODE);
		return TRUE;
	}
	// --------------------------------------------------------------------
}
// END Image_lib Class

/* End of file MY_Image_lib.php */
/* Location: ./app/libraries/MY_Image_lib.php */

設定 MY_ 是在 config.php 裡面的 $config[‘subclass_prefix’]  = ‘MY_ ‘;

依照自己的設定的來跑,就可以出現等比例縮圖的裁切。

只針對 maintain_ratio = FALSE 來做處理。

另外設定了一個 get_info() 來做處理取得圖片內容

You may also like