<?php
/*
* @package LabCMS
* @copyright (c) 2006 Alexander Levin aka Loki (loki_angel@mail.ru)
* @support http://labcms.ru
* @license http://opensource.org/licenses/gpl-license.php GNU Public License
*/
/*
	$file - исходный файл
	$file_dest - файл назначения (если не указан, то выводит на экран)
	$width - макс. ширина
	$height -макс. высота
	$reduce_only - только уменьшать (по уполчанию true)
	$proportional - сохранять пропорции (по уполчанию true)
	$crop - масштабировать по меньшему измерению с обрезкой краев (по уполчанию false)
	$size - вписать в квадрат со стороной size
	$new_type - создать файл с типом отличным от исходного
	
	
	пример
	header('Content-type: image/png');
	$img=new Image_Resize();
	$img->file="path/7329.jpg";
	$img->size=100;
	$img->new_type='png';
	$img->go();
*/

class Image_Resize
{
	public $file;
	public $file_dest=null;
	public $width;
	public $height;
	public $reduce_only=true;
	public $proportional = true;
	public $crop = false;
	public $size = null;
	public $new_type=null;
	public $wm=null;
	public $wm_pos='bottom right';
	public $wm_alpha=30;
	
	protected $image_resized=null;
	
	function go()
	{
		if ($this->size) $this->width=$this->height=$this->size;
		
		$info = getimagesize($this->file);

		$ratio = $this->width/$this->height;

		if (($info[0]<=$this->width) && ($info[1]<=$this->height) && $this->reduce_only && !$this->new_type && !$this->wm) {
			copy($this->file, $this->file_dest);
			return true;
		}

		$src_ratio=$info[0]/$info[1];

		$w_final=$this->width;
		$h_final=$this->height;
		$shift_w=$shift_h=0;

		if ($this->proportional) {
			if ($ratio<$src_ratio && $this->crop) {//более широкий
				$shift_w = -$this->width*($src_ratio/$ratio-1)/2;
				$w_final = $this->width*$src_ratio/$ratio;
			} elseif ($ratio>$src_ratio && $this->crop) {//более высокий
				//если изображение портетно-ориентировано, то смещаем кроп вверх
				// с соотношением 2,5/1
				$shift_h = -$this->height*($ratio/$src_ratio-1)/(2.5+1);
				$h_final = $this->height*($ratio/$src_ratio);
			} elseif ($ratio<$src_ratio) {
				$h_final = $this->height = $this->width/$src_ratio;
				$w_final = $this->width;
			} else {
				$w_final = $this->width = $this->height*$src_ratio;
				$h_final= $this->height;
			}
		} else {
			$w_final=$this->width;
			$h_final=$this->height;
		}
		
		switch ( $info[2] )
		{
			case IMAGETYPE_GIF:
			   $image = @imagecreatefromgif($this->file);
				break;
			case IMAGETYPE_JPEG:
			   $image = @imagecreatefromjpeg($this->file);
				break;
			case IMAGETYPE_PNG:
			   $image = @imagecreatefrompng($this->file);
				break;
			default:
			   return false;
		}
		if (!$image) return false;

		$this->image_resized = imagecreatetruecolor($this->width, $this->height);
		imagecolortransparent($this->image_resized, imagecolorallocate($this->image_resized, 0, 0, 0));
		//imagecolortransparent($this->image_resized, imagecolorallocatealpha($this->image_resized, 255, 0, 0, 127) );
		
		imagealphablending($this->image_resized, false);
		imagesavealpha($this->image_resized, true);

		imagecopyresampled($this->image_resized, $image, $shift_w, $shift_h, 0, 0, $w_final, $h_final, $info[0], $info[1]);

		if ($this->wm) $this->_add_watermark();
		
		if ($this->file==$this->file_dest) {
			@unlink($this->file);
		}
		
		if ($this->new_type=='jpg') $this->new_type='jpeg';
		if ($this->new_type) $info[2]=constant('IMAGETYPE_'.strtoupper($this->new_type));

		switch ( $info[2] )
		{
			case IMAGETYPE_GIF:
				imagegif($this->image_resized, $this->file_dest);
				break;
			case IMAGETYPE_JPEG:
				imagejpeg($this->image_resized, $this->file_dest);
				break;
			case IMAGETYPE_PNG:
				imagepng($this->image_resized, $this->file_dest);
				break;
			default:
				return false;
		}
		return true;
	}
	
	protected function _add_watermark()  
	{
		$watermark = imagecreatefrompng($this->wm);
		// ширина и высота водяного знака
		$wm_width = imagesx($watermark);  
		$wm_height = imagesy($watermark);
		
		$dest_x=$dest_y=0;
		
		if (!is_array($this->wm_pos)) $this->wm_pos=explode(' ', $this->wm_pos);
		foreach ($this->wm_pos as $pos) {
			switch($pos)
			{
				case('left'):
					$dest_x=0;
					break;
				case('right'):
					$dest_x = imagesx($this->image_resized) - $wm_width;
					break;
				case('center'):
					$dest_x = round((imagesx($this->image_resized) - $wm_width)/2);
					break;
				case('top'):
					$dest_y = 0;
					break;
				case('bottom'):
					$dest_y = imagesy($this->image_resized) - $wm_height;
					break;
				case('middle'):
					$dest_y = round((imagesy($this->image_resized) - $wm_height)/2);
					break;
			}
		}
		
		imagecopymerge($this->image_resized, $watermark, $dest_x, $dest_y, 0, 0, $wm_width, $wm_height, $this->wm_alpha);     
	}
}

