Location: PHPKode > scripts > Imaging > imaging-2/class.imaging2.php
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4: */
/*
* (PHP 4 >= 4.0.6, PHP 5) / GD2
*
*/
//if(!defined( 'UKJLIB_MAIN' )){ die( '<a href="http://'.$_SERVER['SERVER_NAME'].'" >'.date("Y-m-d H:i:s").'</a>' ); }



/*
* win/os2 bitmapi tugi
*/
// require_once ( dirname(__FILE__) . '/image_bmp.inc.php' ) ;


/**
* Image manipulation
*
* @author Uku-Kaarel J6esaar <ukjpriee(a(t(pri(d(o(t(ee>
*
* 11:43 21.06.2006
*
* colorDifferRGBOCT renamed colorDiffer
*/
class imaging{

	//{{{ VAR
	/**
	* This is the image
	*/
	var $imageObj = null;

	// var $imageObjArr=array('image'=>null,'mask'=>null,'cache'=>null); // $this->imageObjArr['image','mask','cache']

	var $jpegquality=80;
	var $timelimit=20;
	var $alphaOne='FF00DE';
	var $maxTumbWH = array(120,120);
	var $gdErr = array();

	var $imageObjW = null;
	var $imageObjH = null;
	/**
	* Colorcount
	*/
	var $imageObjColorC = null;
	var $imageObjTC= null;
	/**
	* image type
	* file extension not allowed
	*
	* @var string
	*/
	var $imageOblLT= 'png';
	/**
	* Array supported image types.
	*/
	var $pfu=array();

	var $xbmForeground = '';
	var $wbmpForeground = '';
	var $bmpForeground = '';
/**
* image filename
*/
	var $imageName = 'image';
	//}}}

	
	function imaging( ) { $this->pfu = $this->imagetypes_( ); }
	
	
	
	/**
	* Pixel RGB value in array
	*
	* @param int $x
	* @param int $y
	* @return array array(int r, int g, int b)
	*/
	function pixelRGBarray($x,$y) {
		$pixelindex = ImageColorAt($this->imageObj, $x,$y );
		if( $this->imageObjTC===false )
		{   // indexed colors
			$rgb=imagecolorsforindex($this->imageObj,dechex($pixelindex));
			return array($rgb['red'],$rgb['green'],$rgb['blue']);
		} else {
			return array(($pixelindex>>16)&0xFF,($pixelindex>>8)&0xFF,$pixelindex&0xFF);
		}
	}

	/**
	* Pixel intensity
	*
	* @param int $x
	* @param int $y
	* @param bool $isAlpha FALSE 0-255, TRUE 0-127
	* @return int
	*/
	function pixelIntensity($x,$y,$isAlpha=false)
	{
		if($isAlpha===false){ $d=3; }else{  $d=6; } // [0,254] | [0,127]
		$rgb=$this->pixelRGBarray($x,$y);
		$r = round(  ( $rgb[0] + $rgb[1] + $rgb[2] ) /$d);
		return ($r > 1) ? ($r - 1) : 0;
	}

	/**
	* rgb channel difference
	*
	* @param int $fi usually 0-255
	* @param int $se usually 0-255
	* @return int
	*/
	function channelDifferOCT( $fi=0,$se=255 ) { if($fi>=$se) { return ($fi-$se); } else { return ($se-$fi); } }

	/**
	* pixel difference
	*
	* @param mixed $fi array(r,g,b) or #rrggbb
	* @param mixed $se array(r,g,b) or #rrggbb
	* @return array array(r,g,b)
	*/
	function colorDiffer($fi=false,$se=false)
	{
		$fi=$this->map_PHPOCTHEX($fi,'phparr');
		$se=$this->map_PHPOCTHEX($se,'phparr');

		return array(
			$this->channelDifferOCT($fi[0],$se[0])
			,$this->channelDifferOCT($fi[1],$se[1])
			,$this->channelDifferOCT($fi[2],$se[2])
		);
	}

	/**
	* convert html/css color definition to php array and back to string<br />
	* strip out errors<br />
	*</code>
	* rgb_hex_string( #rrggbb )	to	rgb_oct_array<br />
	* 	and<br />
	* rgb_rgb_string( rgb(int,int%,int) allow '%')	to	rgb_oct_array<br />
	* 	and<br />
	* rgb_oct_array( array(int,int,int) ) to rgb_hex_string<br />
	*
	* //webHEX2rgbOCT  and rgb2webHEX  to map_PHPOCTHEX($input,'phparr|phphex|webhex|webrgb')
	*</code>
	* @param mixed $input array(int_r,int_g,int_b) or string (#) rrggbb
	* @param string $outputformat phparr | phphex | webhex (with '#') | webrgb
	* @return mixed that depends type of $input arr2str (#)rrggbb str2arr
	*
	* @todo rgb() vaildator
	*/
	function map_PHPOCTHEX($input,$outputformat='') {
		// http://www.w3.org/Graphics/Color/sRGB
		$outputformat=strtolower($outputformat);
		$color_a=array();
		$output=null;

		// INPUT TO PHP ARRAY

		if( is_string($input) ) {
			$input =strtolower($input);
			$input =str_replace(array('#',"\n","\t","\r",' '),'',$input);

			// detect HTML/CSS color rgb(rrr,ggg,bbb) format
			if( is_int( strpos($input,'rgb' ) ) ) {

				$bra_stp = strpos($input , '(' );
				$bra_clp = strpos($input , ')' );
				$input = substr($input , $bra_stp+1 , $bra_clp-$bra_stp-1 );

				if (is_int( strpos($input,',') ) ) {

					$input = explode(',' , $input);
					$i=0;
					while ($i<3) {
						if(isset($input[$i])) {
							$input[$i]= trim($input[$i] );

							// % 2 val
							if (strpos($input[$i],'%')) {
								$input[$i]= str_replace('%','',$input[$i]);
								$input[$i]= $this->putInRange($input[$i],0,100);
								$color_a[$i] = ceil($this->percecnt2value($input[$i],255) );
							} else {
								//if int
								$color_a[$i] = $this->putInRange($input[$i],0,255);
							}
						}
						else{ $color_a[$i] =0; }

						$i++;
					}
				} else {
					// if rgb() string not valid
					$input = putInRange( $input, 0,255);
					$color_a = array($input,$input,$input);
				}
			} else {
				// as #hex
				$input = $this->hexColValid($input);
				$input = ltrim($input,'#');

				$color_a[0] = hexdec(substr($input, 0, 2));
				$color_a[1] = hexdec(substr($input, 2, 2));
				$color_a[2] = hexdec(substr($input, -2));
			}
		} elseif (is_array($input) ) {
			$i=0;
			while ($i<3) {
				if(isset($input[$i])){$color_a[$i] = $this->putInRange($input[$i],0,255); }
				else{ $color_a[$i] =0; }
				$i++;
			}

			$color_a = & $input;
		}


		// FORMAT OUTPUT

		switch ($outputformat)	{
		case 'phparr':
			$output = array( $color_a[0], $color_a[1], $color_a[2] );
			break;
		case 'phphex':
			$output = sprintf( "%02x%02x%02x" , $color_a[0] , $color_a[1] , $color_a[2] );
			break;
		case 'webhex':
			$output = sprintf( "%s%02x%02x%02x" , '#' , $color_a[0] , $color_a[1] , $color_a[2] );
			break;
		case 'webrgb':
			$output = 'rgb('. $color_a[0] .','. $color_a[1] .','. $color_a[2] . ')';
			break;
		}

		return $output;
	} // end method map_PHPOCTHEX

	
	/** 
	* return $GradientColor an array that contain the final gradient
	*
	* @param mixed	$coldeb	start color
	* @param mixed	$colfin	final color
	* @param integer 	$n		steps
	* @param string	$foutput	format
	* return array			colors
	*/
	function color_transition($startcol, $endcol, $n,$outpfrmt='phparr' , $shade=false)
	{

		if( $shade===true ) { $n = floor($n/2); }
		
		$b = $this->map_PHPOCTHEX($startcol,'phparr');
		$c = $this->map_PHPOCTHEX($endcol,'phparr');

		$red_start	= $b[0];	$green_start	= $b[1];	$blue_start	= $b[2];
		$red_end	= $c[0];	$green_end  	= $c[1];	$blue_end	= $c[2];	
	
		// difference between start and end
		$colorDif = $this->colorDiffer($b, $c);

		// width of one color step
		$step_red = ( $colorDif[0] / $n) ;
		$step_green = ( $colorDif[1] / $n) ;
		$step_blue = ( $colorDif[2] / $n) ;		
		
		for ($i = 0 ; $i <= $n ; $i++) {
		
			if( $red_start>$red_end ) $red = $red_start - ($step_red * $i);
			else $red = $red_start + ($step_red * $i);

			if( $blue_start>$blue_end ) $blue = $blue_start - ($step_blue * $i);
			else $blue = $blue_start + ($step_blue * $i);
			
			if( $green_start>$green_end ) $green = $green_start - ($step_green * $i);
			else $green = $green_start + ($step_green * $i);
			
			$GradientColor[] = $this->map_PHPOCTHEX( array( round($red) , round($green) , round($blue) ) , $outpfrmt );
		
		}
		
		if( $shade===true ) {
			$ShadeColorRev = Array_reverse($GradientColor);
			array_pop ($GradientColor);
			$shade = Array_merge($GradientColor ,$ShadeColorRev );
			unset($ShadeColorRev);
			unset($ShadeColor);
			if(count($shade)<$n){ $shade[ ] = $shade[ (count($shade)-1) ] ;  }
			return $shade;
		}
		return $GradientColor;
	}	
	

	/**
	* allocate color
	*</code>
	* $this->colorAllocate($WEBHEX,'x',false)
	*</code>
	*
	* @param mixed $WEBHEX array, string
	* @param integer $alpha allocate with this alpha value
	* @param unknown_type $transparent set index traspare
	* @return bool
	*
	* @todo better alpha and transparent support?
	*/
	function colorAllocate($WEBHEX,$alpha='x',$transparent=false)
	{
		$rgb=$this->map_PHPOCTHEX($WEBHEX,'phparr');

		If($alpha!='x' and is_integer($alpha) and function_exists('imagecolorallocatealpha') )
		{
			$c = ImageColorResolveAlpha($this->imageObj, $rgb[0], $rgb[1], $rgb[2], (int)$alpha);
		} else {
			$c = imagecolorresolve($this->imageObj, $rgb[0], $rgb[1], $rgb[2]);
		}

		if($transparent===true) { imagecolortransparent( $this->imageObj, $c ); }

		return $c;
	}

	/**
	* Push integer value into specified range
	*
	* // $v=$this->putInRange($v,0,255);
	*
	* @param int $v value
	* @param int $i min
	* @param int $a	max
	* @return int
	*/
	function putInRange($v,$i=0,$a=255) {if($v>$a){$v=$a;}if($v<$i){$v=$i;}return $v;}

	/**
	* calc real value
	* percent to value
	*
	* ->percecnt2value('50%',255);
	*
	* @param mixed $v percent
	* @param integer $a =100%
	* @return integer
	*/
	function percecnt2value($v=50,$a=255) {$a=(int)$a; if(strpos($v,'%')){$v=trim(str_replace('%','',$v));} $r=(($v*$a)/100); return $r; }

	/**
	* guarantee: rect reside on image
	* if rect begin values is larger than end values, then values changed mutually
	*
	* // 1* kui algus väärtus on lõpu omast suurem, siis muutujate väärtused vahetatakse, lõpp kui võrdsed
	*
	* @param mixed $xs false=0 usually left-top corner
	* @param mixed $ys false=0 usually left-top corner
	* @param mixed $xe false=image width(xmax) usually right-bottom corner
	* @param mixed $ye false=image heighth(ymax) usually right-bottom corner
	* @return array
	*/
	function passXYSE($xs,$ys,  $xe,$ye)
	{
		//vaikimisi
		if($xs===false or $xs<0) { $xs=0; }
		if($ys===false or $ys<0) { $ys=0; }
		if($xs>$this->imageObjW-1) { $xs=$this->imageObjW-1; }
		if($ys>$this->imageObjH-1) { $ys=$this->imageObjH-1; }
		if($xe===false or $xe>$this->imageObjW-1) { $xe=$this->imageObjW-1; }
		if($ye===false or $ye>$this->imageObjH-1) { $ye=$this->imageObjH-1; }

		// 1*
		if($xs>$xe){ $ch=$xe; $xe=$xs; $xs=$ch;}
		if($ys>$ye){ $ch=$ye; $ye=$ys; $ys=$ch;}

		return array($xs,$ys,  $xe,$ye);
	}

	/**
	* Run prepared script
	*
	* @param int $xs start x
	* @param int $ys start y
	* @param int $xe end x
	* @param int $ye end y
	* @param string $method
	* @param bool $stae if true Start $ys=  image bottom line (for win bitmap)
	*/
	function cycle_p($xs=false,$ys=false,  $xe=false,$ye=false,  $method=false,$stae=false)
	{
		list($xs,$ys,  $xe,$ye) = $this->passXYSE($xs,$ys,  $xe,$ye);
		//$xe++;$ye++;
		if($method!==false)
		{
			if($stae===true){
				eval("for(\$y=$ye;\$y>$ys-1;\$y--){for(\$x=$xs;\$x<$xe+1;\$x++){\n$method\n}}");
			}else{
				eval("for(\$y=$ys;\$y<$ye+1;\$y++){for(\$x=$xs;\$x<$xe+1;\$x++){\n$method\n}}");
			}

		}
	} //end method cycle_p

	/**
	* increase or decrease pixel darkness
	*
	* @param array $rgb
	* @param string $act '+' for darking and '-' for lighting
	* @param int $step
	* @return array array(r,g,b)
	*/
	function darkness($rgb=array(127,127,127),$act='+',$step=10)
	{
		if($act=='+'){$act='-';}else{$act='+';}
		eval("
				\$rgb[0]=\$rgb[0]$act\$step;
				\$rgb[0]=\$this->putInRange(\$rgb[0],0,255);

				\$rgb[1]=\$rgb[1]$act\$step;
				\$rgb[1]=\$this->putInRange(\$rgb[1],0,255);

				\$rgb[2]=\$rgb[2]$act\$step;
				\$rgb[2]=\$this->putInRange(\$rgb[2],0,255);
			");
		return $rgb;
	}

	/**
	* intensify pixel color relative importance using complement color
	*  [R]g     [G]b    g[B]
	*
	* @param array $rgb
	* @param int $step how many
	* @return array array(r,g,b)
	*/
	function gammaDiffer($rgb=array(127,127,127),$step=10)
	{
		$leader=max($rgb);
		$ifNot=(255-$step);
		for($i=0;$i<3;$i++)
		{
			if($rgb[$i]==$leader and $rgb[$i]<$ifNot)
			{
				if($i==0){$rgb[$i]=$rgb[$i]+$step; $rgb[1]=$rgb[1]+($step/2);}
				elseif($i==1){$rgb[$i]=$rgb[$i]+$step; $rgb[0]=$rgb[0]+($step/2);}
				elseif($i==2){$rgb[$i]=$rgb[$i]+($step/2); $rgb[1]=$rgb[1]+($step/3);}
			}
			$rgb[$i]=$this->putInRange($rgb[$i],0,255);
		}
		return $rgb;
	}

	/**
	* Create blank image
	*
	* @param int $width
	* @param int $height
	*/
	function imageCreateTCObj($width=400,$height=300)
	{
		if(function_exists('ImageCreateTrueColor'))
		{
			$this->imageObj = @ImageCreateTrueColor($width,$height);
		}
		else { $this->imageObj = @ImageCreate($width,$height); }
		$this->imageOblLT='png';
		$this->imageObjInfo();
		return null;

	}  // end method imageCreateTCObj

	
	/**
	* Return the image types supported by this class
	* @return array image types
	*/
	function imagetypes_() {
		
		$pfu=array();
		
		if( function_exists('imagecreatefromgif') ) { $pfu[] = 'gif'; }
		if( function_exists('imagecreatefromjpg') ) { $pfu[] = 'jpg'; }
		if( function_exists('imagecreatefrompng') ) { $pfu[] = 'png'; }
		if( function_exists('imagecreatefromxbm') ) { $pfu[] = 'xbm'; }
		if( function_exists('imagecreatefromwbmp') ) { $pfu[] = 'wbmp'; }
		if( function_exists('imagecreatefrombmp') ) { $pfu[] = 'bmp'; }
		
		return $pfu;
	}
	
	/**
	* Create a new image from file or URL
	*
	* Usage:
	*</code>
	* $filename = 'myimage.jpg';
	* $imaging_o = new imaging;
	* $imaging_o->imageCreateTCObjFile($filename,false);
	* // now image is loaded
	*
	* $imaging_o->imageCreateTCObjFile($filename,false);
	*</code>
	* @param string $filepath
	* @param bool $returnObj true = return imageobject at once
	* @return mixed bool or image object
	*/
	function imageCreateTCObjFile($filepath,$returnObj=false)
	{
		if($returnObj===false){ $this->nullImageObj(); }

		if(strstr(strtolower($filepath),'.swf') ) {
			$this->imageOblLT='swf';
			$this->imageObj=$filepath;
			$this->imageObjInfo('swf');
		}
		foreach( $this->pfu as $pfun)
		{
			// proovitakse avada nii, siis ei ole kindel faili nimekuju nõutud
			// ja funktsioon töötab ka vaneam php peal $s=gd_info();
			if(function_exists('imagecreatefrom'.$pfun))
			{
				eval("\$j=@imagecreatefrom".$pfun."('".$filepath."');");
				if($j!='')
				{
					$this->imageObj=$j;
					$this->imageOblLT=$pfun;
					$this->imageObjInfo();
					if($returnObj===true){return $j;}
				}
				unset($j);
			}
		}
	}  // end method imageCreateTCObjFile

	/**
	* Create a new image from the image stream in the string or base64 string
	* maybe you need use stripslashes()
	*
	* @param string $string
	* @param bool $returnObj if you want return image object
	* @return mixed return imageobject if you want, else bool
	*/
	function imageCreateTCObjStr($string,$returnObj=false)
	{
		//string
		$this->nullImageObj();

		// str
		$this->imageObj = @imagecreatefromstring($string);
		if ($this->imageObj===false)
		{
			// base64 str
			$this->nullImageObj();
			$string=base64_decode($string); $this->imageObj =null;
			$this->imageObj = @imagecreatefromstring($string);
		}

		if ($this->imageObj===false)
		{
			$this->nullImageObj();
		}

		if ($this->imageObj!==false) {
			unset( $string );
			$this->imageOblLT='png';
			$this->imageObjInfo();
		}

		if($returnObj===true){return $this->imageObj;}
		return true;
	} // end method imageCreateTCObjStr

	/**
	* Create a new image from the object (resource id#)
	*
	* Usage:
	*<code>
	* $im = imagecreatefromjpg($filename);
	* $imaging_o = new imaging;
	* $imaging_o->imageCreateTCObjObj($im);
	* // now image is loaded
	*</code>
	* @param object $Obj resource id
	*/
	function imageCreateTCObjObj($Obj)
	{
		if ($this->imageObj=!$Obj) { $this->nullImageObj(); }
		$this->imageObj=$Obj;
		unset($Obj);
		$this->imageObjInfo();
		if($this->imageObjTC=false)
		// GIF89a
		$this->imageOblLT='png';
	} // end method imageCreateTCObjObj

	/**
	* Free imageobject, free memory
	*/
	function nullImageObj()
	{
		if(function_exists('imagedestroy') ){
			if( strtolower($imageOblLT)!='gif'){
				@imagedestroy($this->imageObj);
			}
		}
		$this->imageObj=null;
	}

	/**
	* Read and set imageinfo
	*<code>
	* if $o===true
	* array( (int) img W , (int) img H , (int) num_of_colors , (bool) is_truecolor,(string) img_sourcefile_type )
	*
	* if $o=='swf'
	* array( (int) img W , (int) img H , (int) 64 , (bool) is_truecolor )
	*</code>
	* @param boolean $o TRUE output info array, FALSE update, 'swf' current image is swf
	* @return mixed void or return simple info array;
	*/
	function imageObjInfo($o=false)
	{

		if($o===false)
		{
			set_time_limit($this->timelimit);
			@imageinterlace($this->imageObj,1);
			@imagealphablending($this->imageObj, true);

			$this->imageObjW = imagesx($this->imageObj);
			$this->imageObjH = imagesy($this->imageObj);
			$this->imageObjColorC = imagecolorstotal($this->imageObj);

			// indexed color or truecolor
			if( function_exists('imageistruecolor'))
			{
				//(PHP 4 >= 4.3.2, PHP 5) GD 2.0.1
				$this->imageObjTC=imageistruecolor($this->imageObj);
			} else {
				if( $this->imageObjColorC<=255 ){ $this->imageObjTC=true; }
				else { $this->imageObjTC=false; }
			}
		}

		if( strtolower($o)=='swf')
		{
			$imagename_i=getimagesize( $this->imageObj );
			$this->imageObjW = $imagename_i[0];
			$this->imageObjH = $imagename_i[1];
			return array($this->imageObjW,$this->imageObjH,64,true);
		}

		if($o===true)
		{
			return array($this->imageObjW,$this->imageObjH,$this->imageObjColorC,$this->imageObjTC,$this->imageOblLT);
		}

	} // end method imageObjInfo

	/**
	* Read image pixel by pixel and write them as html table cells
	*
	* !!! Best for small images (thumb and icon size) !!!
	*
	* //teeb pildist html tabeli
	*
	* @param int $cell html table cell width and height
	* @return string
	*/
	function imageObjHTMLTABLE($cell=9)
	{
		$rows='';
		$row='';
		//pildi ridu arv kordi
		for($iy=0;$iy<$this->imageObjH;$iy++)
		{
			//reapikkus arv kordi
			$row='';
			for($ix=0;$ix<$this->imageObjW;$ix++)
			{
				$rgb = $this->pixelRGBarray($ix,$iy);
				$webhex = $this->map_PHPOCTHEX(array($rgb[0],$rgb[1],$rgb[2]),'webhex');

				if("#".strtolower($this->alphaOne)==$webhex){$webhex="transparent";}
				$row.=" <!-- $rgb[0] $rgb[1] $rgb[2] --><td style=\"background:$webhex\" width=\"$cell\" height=\"$cell\"></td> \n";
			}
			$rows.="\n<tr style=\"background:transparent;border:0px none transparent;\">$row</tr>\n\n";
		}

		return  "\n\n<table style=\"background:transparent;border:0px none transparent;\" cellpadding='0' cellspacing='0'>\n\n"
		."\n$rows\n"
		."</table>\n\n\n";
	}

	/**
	* Create greyscale or black-white area on the image
	*
	* @param mixed $xs start x ; if false then 0
	* @param mixed $ys start y ; if false then 0
	* @param mixed $xe end x ; if false then image width
	* @param mixed $ye end y ; if false then image height
	* @param int $s 1-256 number of colors
	*/
	function greyscale($xs=0,$ys=0,  $xe=false,$ye=false,  $s=256 )
	{
		$s=$this->putInRange($s,1,256);
		$m=round(256/$s); // astme suurus

		$model="\$cSum=\$this->pixelIntensity(\$x,\$y,false);\n";

		// kui 2 tooni, siis must ja valge
		// black and white
		if( $s<3 ) { $model .="if(\$cSum>127){\$cSum=255;}else{\$cSum=0;}\n"; }
		else { $model .="for(\$cSumi=0; (\$cSumi+$m)<=\$cSum; ){ if(\$cSumi+$m>\$cSum )break; else \$cSumi += $m; \n }";  }
		$method="
			$model
			imagesetpixel(\$this->imageObj,\$x,\$y,imagecolorresolve(\$this->imageObj,\$cSumi,\$cSumi,\$cSumi));
			";

		$this->cycle_p( $xs,$ys,  $xe,$ye,  $method );

	}  //end method greyscale

	
	/**
	* Rasterize. If amount 3-4, shaded cells are drawed
	*
	* @param int $x
	* @param int $y
	* @param int $w
	* @param int $h
	* @param int $am amount 1-4 
	*/
	function rasterize($x=0,$y=0,  $w=false,$h=false, $am=1) {
		
		$am=$this->putInRange($am,1,4); //1=2x2 rect, 2=3x3 3=4x4
		if($am==1)$a=4;
		if($am==2)$a=8;
		if($am==3)$a=16;
		if($am==4)$a=32;
		
		$tw=round($w/$a);
		$th=round($h/$a);
		$csw=round($w/$tw);
		$csh=round($h/$th);
		
		$tmpImg=imagecreatetruecolor($tw,$th);
		
		//kopeerib väiksemaks
		if( function_exists('ImageCopyResampled') )
		{
			ImageCopyResampled( $tmpImg, $this->imageObj, 0, 0, $x, $y, $tw,$th, $w, $h );
		} else {
			imagecopyresized( $tmpImg, $this->imageObj, 0, 0, $x, $y, $tw,$th, $w, $h );
		}		
								
		if($a>8) {
			$a2=ceil($a/2);
			$tmpxmax=$w-$a;
			$tmpymax=$h-$a;
			for($tmpx=0;$tmpx<=$tmpxmax;) {  
				for($tmpy=0;$tmpy<=$tmpymax;) {

					$pixelindex = ImageColorAt($this->imageObj, $x+$tmpx+$a2,$y+$tmpy+$a2 );
					$rgb = array(($pixelindex>>16)&0xFF,($pixelindex>>8)&0xFF,$pixelindex&0xFF);

					$lighted=$this->darkness($rgb , '-',10);
					$darked=$this->darkness($rgb , '+',10);
					
					$this->gradient_room($lighted,$darked,$x+$tmpx,$y+$tmpy,$a,$a,false);
					
					$tmpy=$tmpy+$a;
				}
				$tmpx=$tmpx+$a;
			}	
		} else {
			// kopeerib suuremaks tagsi
			imagecopyresized( $this->imageObj, $tmpImg, $x, $y, 0, 0, $w, $h, $tw,$th );		
		}
	}	//end method rasterize
	
	/**
	* colorize/tint effect applied specified area on image
	*
	* @param int $xs rect start x ; if false then 0
	* @param int $ys rect start y ; if false then 0
	* @param int $xe rect end x ; if false then image width
	* @param int $ye rect end y ; if false then image height
	* @param mixed $colourize array(r,g,b) or string #rrggbb
	* @param void
	*/
	function colourize($xs=0,$ys=0,  $xe=false,$ye=false,   $colourize='D3C17B', $intens=0.25)
	{
		list($xs,$ys,  $xe,$ye) = $this->passXYSE($xs,$ys,  $xe,$ye);
		if(!is_array($colourize) and $colourize!==false){ $colourize=$this->map_PHPOCTHEX($colourize,'phparr'); }

		$intens=$this->putInRange($intens,0,1);


		//  if( function_exists('imagefilter')===true  )
		//  { return imagefilter( $this->imageObj, IMG_FILTER_COLORIZE ,$colourize[0] ,$colourize[3] ,$colourize[2] ); }

		$method = "
					\$rgba=\$this->pixelRGBarray(\$x,\$y);
					\$dif=\$this->colorDiffer(\$rgba,array(".$colourize[0].",".$colourize[1].",".$colourize[2]."));
			";

		for($i=0;$i<3;$i++)
		{
			$method .= "
			if(\$rgba[$i]<".$colourize[$i]."){ \$set$i=\$rgba[$i]+(\$dif[$i]*$intens); }
			if(\$rgba[$i]>".$colourize[$i]."){ \$set$i=\$rgba[$i]-(\$dif[$i]*$intens); }
			if(\$set$i>255){\$set$i=".$colourize[$i].";}
			if(\$set$i<0){\$set$i=0;}
			";
		}

		$method .= "
			imagesetpixel(\$this->imageObj, \$x, \$y, imagecolorresolve(\$this->imageObj, \$set0,\$set1,\$set2 ));
			";
		$this->cycle_p( $xs,$ys,  $xe,$ye, $method );

	}  //end method colourize

	/**
	* Write shadowed text on the image
	*
	* //lihtsa varjuga tekst pildile
	*
	*PHP GD Fonts
	*<code>
	* // 1 w:5 h:8
	* // 2 w:6 h:13
	* // 3 w:7 h:13
	* // 4 w:8 h:16
	* // 5 w:9 h:15
	* // echo '1 w:'.imagefontwidth(1).' h:'.imagefontheight(1).'<br />';
	*</code>
	* @param string $text
	* @param string $fg text color
	* @param string $fgf shadow color
	* @param mixed $font GD font num or the path to the TrueType font you wish to use.
	* @param int $x
	* @param int $y
	* @param int $ttfSize The font size.
	* @param int $ttfRo if TTF The angle in degrees
	*/
	function writeString($text='',$fg='000000',$fgf='000000',$font=1,$x,$y,$ttfSize=12,$ttfRot=0)
	{
		$ttfSize = (integer) $ttfSize;
		$ttfRot = (integer) $ttfRot;
		$fg =$this->colorAllocate($fg,'x',false);

		// isTTF
		if( !is_int($font) )
		{
			//$bounds = ImageTTFBBox($ttfSize, $ttfRot, $font, "W");
			if( $fgf!=null and $fgf!==false and !empty($fgf) )
			{
				$fgf =$this->colorAllocate($fgf,'x',false);
				//vari                   //  siz  rot x y
				imagettftext($this->imageObj, $ttfSize, $ttfRot, $x+1, $ttfSize+$y-1, $fgf, $font, $text);
				imagettftext($this->imageObj, $ttfSize, $ttfRot, $x+1, $ttfSize+$y, $fgf, $font, $text);
				imagettftext($this->imageObj, $ttfSize, $ttfRot, $x+1, $ttfSize+$y+1, $fgf, $font, $text);
			}

			//tekst
			imagettftext($this->imageObj, $ttfSize, $ttfRot, $x, $ttfSize+$y, $fg, $font, $text);

		} else {
			if( $fgf!=null and $fgf!==false and !empty($fgf) )
			{
				$fgf =$this->colorAllocate($fgf,'x',false);
				// vari
				ImageString($this->imageObj, $font , $x+1, $y-1, $text, $fgf);
				ImageString($this->imageObj, $font , $x+1, $y, $text, $fgf);
				ImageString($this->imageObj, $font , $x+1, $y+1, $text, $fgf);
			}
			ImageString($this->imageObj, $font , $x, $y, $text, $fg);
		}
	}

	/**
	* Draw line on the image. See phpmanual imageline
	*
	* // otsad lopevad risti joonselt
	*
	* @param int $pxs
	* @param int $pys
	* @param int $pxe
	* @param int $pye
	* @param int $l
	* @param string $c
	* @return bool
	*/
	function ImageLine_($pxs,$pys,   $pxe,$pye,  $l=1,$c='000000')
	{
		$c=$this->colorAllocate($c,'x',false);

		if ($l == 1) {
			//return imageline($image, $x1, $y1, $x2, $y2, $color);
			return imageline($this->imageObj,  $pxs,$pys,   $pxe,$pye,  $c );
		}
		$t = $l / 2 - 0.5;
		if ($pxs == $pxe || $pys == $y2) {
			return imagefilledrectangle(	$this->imageObj, round(min($pxs, $pxe) - $t)
			, round(min($pys, $pye) - $t)
			, round(max($pxs, $pxe) + $t)
			, round(max($pys, $pye) + $t)
			, $c
			);
		}
		$k = ($pye - $pys) / ($pxe - $pxs); //y = kx + q
		$a = $t / sqrt(1 + pow($k, 2));
		$points = array(
		round($pxs - (1+$k)*$a), round($pys + (1-$k)*$a),
		round($pxs - (1-$k)*$a), round($pys - (1+$k)*$a),
		round($pxe + (1+$k)*$a), round($pye - (1-$k)*$a),
		round($pxe + (1-$k)*$a), round($pye + (1+$k)*$a),
		);
		imagefilledpolygon($this->imageObj, $points, 4, $c);
		return imagepolygon($this->imageObj, $points, 4, $c);

	}  //end method ImageLine_

	/**
	* draw frame. 'n' is default/previous value;
	*
	* @param int $x start x
	* @param int $y start y
	* @param int $w width
	* @param int $h height
	* @param string $tc border color #rrggbb top
	* @param string $rc border color #rrggbb right
	* @param string $bc border color #rrggbb bottom
	* @param string $lc border color #rrggbb left
	* @param string $tl border size  px top
	* @param string $rl border size  px right
	* @param string $bl border size  px bottom
	* @param string $ll border size  px left
	*/
	function frame($x=0,$y=0,$w=1,$h=1,   $tc='n',$rc='n',$bc='n',$lc='n',    $tl=1,$rl='n',$bl='n',$ll='n')
	{
		if($tc=='n'){$tc='808080';}
		if($rc!='n' and $rc==''){$rc=$tc;}
		if($bc!='n' and $bc==''){$bc=$rc;}
		if($lc!='n' and $lc==''){$lc=$bc;}

		if($tl=='n'){$tl=1;}
		if($rl!='n' and $rl==''){$rl=$tl;}
		if($bl!='n' and $bl==''){$bl=$rl;}
		if($ll!='n' and $ll==''){$ll=$bl;}

		// define new reference points: clockwise numeration; start upper left with 0/0
		$fr_pos = array ( "XY0" => array($x,$y)           //top
		,"XY1" => array($x+$w-1,$y)      //rig
		,"XY2" => array($x+$w-1,$y+$h-1) //lef
		,"XY3" => array($x,$y+$h-1)      //bot
		);

		$this->ImageLine_($fr_pos[XY0][0],$fr_pos[XY0][1],$fr_pos[XY1][0],$fr_pos[XY1][1],  $tl,$tc);   //top
		$this->ImageLine_( $fr_pos[XY1][0],$fr_pos[XY1][1],$fr_pos[XY2][0],$fr_pos[XY2][1], $rl,$rc );  //rig
		$this->ImageLine_( $fr_pos[XY3][0],$fr_pos[XY3][1],$fr_pos[XY2][0],$fr_pos[XY2][1], $bl,$bc );  //bot
		$this->ImageLine_( $fr_pos[XY0][0],$fr_pos[XY0][1],$fr_pos[XY3][0],$fr_pos[XY3][1], $ll,$lc );  //lef

	}

	/**
	* Draw shadow right and bottom side on the image.
	*<code>
	* //-------------
	* //|           L
	* //|           L
	* //|           L
	* //|LLLLLLLLLLLL
	*</code>
	* // joonistab pildi ümber varjuvärvilise raami 1px ja varju laiusega $len
	*
	* @param string $shadCol Shadow color
	* @param string $bgCol Usually same as HTML BODY bgColor or TABLE bgColor
	* @param int $len Shadow lenght
	* @param int $frameL
	* @param boolean $isOut TRUE = image enlarged FALSE = do not change current image size
	*/
	function shadowAdd($shadCol='838383',$bgCol='FFFFFF',$len=5,$frameL=2,$isOut=true)
	{
		if( $isOut===false)
		{
			// Current_img_size - frame_size - shadow_size // raamitava mõõt (orig - raam - vari)
			$pimW=$this->imageObjW-($frameL*2)-$len;
			$pimH=$this->imageObjH-($frameL*2)-$len;

			// temporary image // pildisuurune ala
			$pimg = ImageCreateTrueColor($this->imageObjW,$this->imageObjH);
			$bgColor=$this->colorAllocate($bgCol,'x',false); //lopppilt esmalt taustavarviline
			ImageFill( $pimg,0,0,$bgColor );
			// now we resize current image // pilt väiksemaks
			$this->imageCropyze( $pimW-($frameL*0),$pimH-($frameL*0),   false,false,   0,0,  0,0  );

			// // kopeeritakse sellele
			@imagecopy( $pimg, $this->imageObj,  $frameL,$frameL, 0,0, $pimW+($frameL*2),$pimH+($frameL*2));

		}  else {
			// raamitava mõõt // orig // pildi mõõt nüüd (orig + raam + vari)
			$pimW=$this->imageObjW+($frameL*2)+$len;
			$pimH=$this->imageObjH+($frameL*2)+$len;
			//suurem tyhjade äärtega pilt
			$pimg = ImageCreateTrueColor($pimW,$pimH);
			$bgColor=$this->colorAllocate($bgCol,'x',false); //lopppilt esmalt taustavarviline
			ImageFill( $pimg,0,0,$bgColor );

			@imagecopy( $pimg, $this->imageObj,  $frameL,$frameL, 0,0, $pimW+($frameL*2),$pimH+($frameL*2));

			$pimW=$this->imageObjW;
			$pimH=$this->imageObjH;
		}

		//äärtest tyhi pilt nüüd
		$this->imageObj=$pimg;
		$lwp = round($frameL/2); //pool joone paksust
		//frame
		$this->frame($lwp,$lwp,$pimW+($frameL*1),$pimH+($frameL*1),   $shadCol,$shadCol,$shadCol,$shadCol,    $frameL,$frameL,$frameL,$frameL);

		//shadow right    //shadow bottom
		$this->gradient_vertical($shadCol,$bgCol,   $pimW+(2*$frameL) , $len,   $len , $pimH+(3*$frameL)-$len   );
		$this->gradient_horizontal($shadCol,$bgCol,  $len , $pimH+(2*$frameL) ,  $pimW+(2*$frameL)-$len , $len  );
		
		//cor top right		//cor bottom right		//cor bottom left 
		$this->gradient_cor($shadCol,$bgCol,	$pimW+(2*$frameL) ,	0,  					$len , 1 );
		$this->gradient_cor($shadCol,$bgCol,	$pimW+(2*$frameL),	$pimH+(2*$frameL) ,	$len , 2 );
		$this->gradient_cor($shadCol,$bgCol,	0,					$pimH+(2*$frameL) ,	$len , 3 );
		
		// update image info
		$this->imageObjW=ImageSX($this->imageObj);
		$this->imageObjH=ImageSY($this->imageObj);
	}

	/**
	* Convert string to valid hex value #rrggbb
	* v 1.1 3:10 16.06.2006(nightly update)
	*<code>
	* //00 00 00 	//	'' or 0
	* //11 11 11 	//	1
	* //11 12 22 	//	12
	* //11 22 33 	//	123
	* //12 34 44 	//	1234
	* //12 34 55 	//	12345
	*
	* // ->hexColValid('#&+;=LMR]x[');
	*</code>
	* @param string $hexCol
	* @return strinf
	*/
	function hexColValid($hexCol='') {
		$hexCol=ltrim($hexCol,'#');
		$len=strlen($hexCol);
		$hexCol_tmp='';
		$i=0;

		//Push into valid range		ANSI 48-57,65-70,97-102
		while ($i<$len) {
			$c=$hexCol{$i};
			if(ord($c)<48 ){ $hexCol_tmp.='0'; } //<< 0
			elseif (ord($c)>57 and ord($c)<65){ $hexCol_tmp.='a'; } // 9>><<A
			elseif (ord($c)>70 and ord($c)<84){ $hexCol_tmp.='f'; } // F>><<S
			elseif (ord($c)>84 and ord($c)<97){ $hexCol_tmp.='a'; } // F>><<S>><<a
			elseif (ord($c)>102 ){ $hexCol_tmp.='f'; } //f>>
			else { $hexCol_tmp.=$c; }
			$i++;
		}

		$hexCol=strtolower($hexCol_tmp);		

		switch ( $len ) {
		
			case 1:
				// 1 | 11111
				$hexCol= str_repeat($hexCol,6);
				break;
			case 2:
				// 12 | 111 222	
				$hexCol=str_repeat($hexCol,3);
				break;
			case 3:
				// 123 | 112233
				$hexCol=str_repeat($hexCol{0} ,2) . str_repeat($hexCol{1} ,2) . str_repeat($hexCol{2} ,2);
				break;
			case 4:
				// 1234 // 123434
				$hexCol=substr($hexCol,0,2) .  str_repeat(substr($hexCol,2,2) ,2) ;
				break;
			case 5:
				// 12345 | 123455
				$hexCol=substr($hexCol,0,2) . substr($hexCol,2,2) . str_repeat(substr($hexCol,4,1),2) ;
				break;
			case ($len>=6):
				// 112233>
				$len3=floor($len/3);
				
				$hexCol_tmp = substr($hexCol,0,$len3); 
				if( hexdec($hexCol_tmp)>255 ) { $hexCol_tmp=dechex(255); }
				$hexCol.=$hexCol_tmp;
				
				$hexCol_tmp = substr($hexCol,2,$len3); 
				if( hexdec($hexCol_tmp)>255 ) { $hexCol_tmp=dechex(255); }
				$hexCol.=$hexCol_tmp;
				
				$hexCol_tmp = substr($hexCol,4,$len3); 
				if( hexdec($hexCol_tmp)>255 ) { $hexCol_tmp=dechex(255); }
				$hexCol.=$hexCol_tmp;
		}
		
		$hexCol_tmp='';
		$hexCol='#'.$hexCol;

		return $hexCol;
	}

	/**
	* Color transition. vertical.
	*
	* @param mixed $startcol
	* @param mixed $endcol
	* @param int $gx top-left corner x
	* @param int $gy top-left corner y
	* @param int $width
	* @param int $height
	* @param bool $shade
	*/
	function gradient_vertical($startcol='000000',$endcol='FFFFFF',$gx=0,$gy=0,$width=100,$height=10,$shade=false) {
		// there is greadiend array // array(  0 =>array( 0=>r,1=>g,2=>b)  ); 
		$gcol_a = $this->color_transition($startcol , $endcol, $width ,'phparr',$shade);
		$height = $gy+$height-1;
		//PREPARE
		$evalExec="
				for (\$pos=0; \$pos<$width;\$pos++) {
					\$color = ImageColorAllocate(\$this->imageObj,\$gcol_a[\$pos][0],\$gcol_a[\$pos][1],\$gcol_a[\$pos][2]);
					imageline( \$this->imageObj, $gx+\$pos,$gy,    $gx+\$pos,$height,\$color);
				}
		";
		// EXECUTE
		eval($evalExec);	
	}

	/**
	* Color transition. horizontal.
	*
	* @param mixed $startcol
	* @param mixed $endcol
	* @param int $gx top-left corner x
	* @param int $gy top-left corner y
	* @param int $width
	* @param int $height
	* @param bool $shade
	*/
	function gradient_horizontal($startcol='000000',$endcol='FFFFFF',$gx=0,$gy=0,$width=100,$height=10,$shade=false) {
		$gcol_a = $this->color_transition($startcol , $endcol, $height ,'phparr',$shade);
		$width=$width+$gx-1;
		//PREPARE 
		$evalExec="
				for (\$pos=0; \$pos<$height;\$pos++) {
					\$color = ImageColorAllocate(\$this->imageObj,\$gcol_a[\$pos][0],\$gcol_a[\$pos][1],\$gcol_a[\$pos][2]);
					imageline( \$this->imageObj, $gx,$gy+\$pos,    $width,$gy+\$pos,\$color);
				}
		";
		// EXECUTE
		eval($evalExec);	

		
	}
	/**
	* Color transition. diagonals.
	*
	* @param mixed $startcol
	* @param mixed $endcol
	* @param int $gx top-left corner x
	* @param int $gy top-left corner y
	* @param int $width
	* @param int $height
	* @param bool $shade
	*/
	function gradient_diagonals($startcol='000000',$endcol='FFFFFF',$gx=0,$gy=0,$width=100,$height=10,$evalExec_i='',$shade=false ) {
		$cy=0;
		$gcol_a = $this->color_transition($startcol , $endcol,  (2*$width) ,'phparr',$shade);
		$sonh=$height/$width; // exact how many lines need draw per one cycle
		$sonh_cs=ceil($sonh); // entrie lines
		$sonh_csa=$sonh/$sonh_cs; // exact y cordinate
		$evalExec="
		while( \$i<\$width ) {
			\$colorT = ImageColorAllocate(\$this->imageObj , \$gcol_a[\$i][0],\$gcol_a[\$i][1],\$gcol_a[\$i][2]);
			\$colorB = ImageColorAllocate(\$this->imageObj , \$gcol_a[(\$i+\$width)][0],\$gcol_a[(\$i+\$width)][1],\$gcol_a[(\$i+\$width)][2]);
			
			/*	Wn aüüq öryth wbohq: zn cbyr ranz ybyy \n wn öryth evxnf: zhy ba irry enun! */
			
			\$iy=0;
			while( \$iy<\$sonh_cs ) {
				$evalExec_i
				if( \$iy>=\$sonh or \$cy==\$height ) break;
				if( \$sonh>1 ) { \$cy=\$cy+\$sonh_csa; } else { \$cy=\$cy+\$sonh; } // täpne joone asukoht
				\$iy++;
			}
			\$i++;
		}
		";
		eval( $evalExec );
	} // gradient_diagonals
	
	
	/**
	* Color transition. diagonal 1.
	*
	* @param mixed $startcol
	* @param mixed $endcol
	* @param int $gx top-left corner x
	* @param int $gy top-left corner y
	* @param int $width
	* @param int $height
	* @param bool $shade
	*/	
	function gradient_diagonal($startcol='000000',$endcol='FFFFFF',$gx=0,$gy=0,$width=100,$height=10,$shade=false) { 
		$evalExec =" 
		imageline( \$this->imageObj, 	\$gx+\$i,\$gy,	    \$gx,\$gy+\$cy,	\$colorT); // YL
		imageline( \$this->imageObj,	\$gx+\$i,\$gy+\$height-1,	\$gx+\$width,\$gy+\$cy,	\$colorB); // AL
		";
		$this->gradient_diagonals($startcol,$endcol,$gx,$gy,$width,$height,$evalExec,$shade);
		
	}
	
	/**
	* Color transition. diagonal 2.
	*
	* @param mixed $startcol
	* @param mixed $endcol
	* @param int $gx top-left corner x
	* @param int $gy top-left corner y
	* @param int $width
	* @param int $height
	* @param bool $shade
	*/	
	function gradient_r_diagonal($startcol='000000',$endcol='FFFFFF',$gx=0,$gy=0,$width=100,$height=10,$shade=false) { 
		$evalExec ="
		imageline( \$this->imageObj, 	\$gx+\$width-\$i,\$gy,	    \$gx+\$width,\$gy+\$cy,	\$colorT); // YL
		imageline( \$this->imageObj,	\$gx+\$width-\$i-1,\$gy+\$height-1,	\$gx,\$gy+\$cy,	\$colorB); // AL
		";
		$this->gradient_diagonals($startcol,$endcol,$gx,$gy,$width,$height,$evalExec,$shade);
	
	}
	/**
	*  gradient filled sphere
	*
	* @param string $startcol Outer
	* @param string $endcol Center
	* @param int $gx top-left corner x
	* @param int $gy top-left corner y
	* @param int $width
	* @param int $height
	* @param bool $shade
	*/
	function gradient_sphere($startcoli='000000',$endcoli='FFFFFF',$gx=0,$gy=0,$width=100,$height=100,$shade=false) {

		$startcol = $this->map_PHPOCTHEX($startcoli,'phparr');
		$endcol = $this->map_PHPOCTHEX($endcoli,'phparr');		
		
		if($height>$width)$lenght=$width;
		elseif($height<$width)$lenght=$height;
		else $lenght=$width;		
		
		// there is greadiend array // array( 0=>r,1=>g,2=>b);
		$gcol_a = $this->color_transition($startcol , $endcol, $lenght ,'phparr',$shade);		
				
		$bgColor=$this->colorAllocate($startcol,'x',false);
		imagefilledrectangle ( $this->imageObj,	$gx,$gy,	$gx+$width,$gy+$height, $bgColor );
		// PREPARE
				
		$evalExec="
				for (\$pos=0; \$pos<$lenght;\$pos++) {
					\$color = ImageColorAllocate(\$this->imageObj ,\$gcol_a[\$pos][0],\$gcol_a[\$pos][1],\$gcol_a[\$pos][2]);
					imagefilledellipse(\$this->imageObj," . ($gx+floor($width/2)) . ',' . ($gy+floor($height/2)) . " , $lenght-\$pos, $lenght-\$pos ,\$color );
				}
		";
		// EXECUTE
		eval($evalExec);

	}

	/**
	*  gradient room. 1/3 of image height and start at outside
	*
	* @param string $startcol Outer
	* @param string $endcol Center
	* @param int $gx top-left corner x
	* @param int $gy top-left corner y
	* @param int $width
	* @param int $height
	* //@param bool $shade
	*/
	function gradient_room($startcol='000000',$endcol='FFFFFF',$gx=0,$gy=0,$width=100,$height=100,$shade=false) {

		$bgColor=null;
		$startcol = $this->map_PHPOCTHEX($startcol,'phparr');
		$endcol = $this->map_PHPOCTHEX($endcol,'phparr');		
		
		$shadeLen=ceil($height/3);
		$shadeW=ceil($width/4);
		
		// there is greadiend array // array( 0=>r,1=>g,2=>b);
		$gcol_a = $this->color_transition($startcol , $endcol, $shadeLen,'phparr',$shade);		
		
		if($shade===true) $bgColor=$this->colorAllocate($startcol,'x',false);
		else $bgColor=$this->colorAllocate($endcol,'x',false);
		
		imagefilledrectangle ( $this->imageObj,	$gx,$gy,	$gx+$width,$gy+$height, $bgColor );
		
		// PREPARE
		$evalExec="
				for (\$pos=0; \$pos<$shadeLen;\$pos++) {
					\$color = ImageColorAllocate(\$this->imageObj ,\$gcol_a[\$pos][0],\$gcol_a[\$pos][1],\$gcol_a[\$pos][2]);
					
					imageline(\$this->imageObj, $gx+\$pos, $gy+\$pos, $gx+\$pos, $gy+$height-\$pos, \$color); // L
					imageline(\$this->imageObj, $gx+\$pos, $gy+\$pos, $gx+$width-\$pos, $gy+\$pos, \$color); // T
					imageline(\$this->imageObj, $gx+$width-\$pos, $gy+$height-\$pos, $gx+$width-\$pos, $gy+\$pos, \$color); // R
					imageline(\$this->imageObj, $gx+\$pos, $gy+$height-\$pos, $gx+$width-\$pos, $gy+$height-\$pos, \$color); // B
				}
		";
		// EXECUTE
		eval($evalExec);

	}	
	
	
	/**
	* Apply gradient on specified area
	* radial quarter [|_] [_|] [|-] [7]
	*
	* @param string $startcol #rrggbb
	* @param string $endcol #rrggbb
	* @param int $gx top-left corner x
	* @param int $gy top-left corner y
	* @param int $width
	* @param int $height
	* @param string $dir direction
	* @param int $vp
	*/
	function gradient_cor($startcol='000000',$endcol='FFFFFF',$gx=0,$gy=0,$len=50,$dir=1 ) {
		$startcol = $this->map_PHPOCTHEX($startcol,'phparr');
		$endcol = $this->map_PHPOCTHEX($endcol,'phparr');
		$lenc=(2*$len)-1;

		// there is greadiend array // array( 0=>r,1=>g,2=>b);
		$gcol_a = $this->color_transition($startcol , $endcol, $lenc+3 ,'phparr');

		$gxw= (int)($gx+$len);
		$gyh= (int)($gy+$len);
				
		// PREPARE DIRECTION -- TYPE
		    if($dir==0){ $evalExec_dirtype = " imagearc(\$this->imageObj, $gxw,$gyh, 	\$pos,	\$pos, 180, 270, \$color); "; } //TL
		elseif($dir==1){ $evalExec_dirtype = " imagearc(\$this->imageObj, $gx,$gyh,		\$pos,	\$pos, 270,   0, \$color); "; } //TR
		elseif($dir==2){ $evalExec_dirtype = " imagearc(\$this->imageObj, $gx,$gy,		\$pos,	\$pos,   0,  90, \$color); "; } //BR
		elseif($dir==3){ $evalExec_dirtype = " imagearc(\$this->imageObj, $gxw,$gy,		\$pos,	\$pos,  90, 180, \$color); "; } //BL
		
		// EXECUTE
		imagefilledrectangle ( $this->imageObj,	$gx,$gy,	$gxw,$gyh, $this->colorAllocate($endcol,'x',false) );

		$evalExec="
				for (\$pos=0; \$pos<$lenc; \$pos++) {
					\$color = ImageColorAllocate(\$this->imageObj,\$gcol_a[\$pos][0],\$gcol_a[\$pos][1],\$gcol_a[\$pos][2]);
					$evalExec_dirtype
				}
		";
		eval($evalExec);

	}  // end method gradient


	/**
	* image rotate
	*
	* @param int $degrees
	*/
	function ImageRotate($degrees=0)
	{
		//list($xs,$ys,  $xe,$ye) = $this->passXYSE($xs,$ys,  $xe,$ye);
		//,   $xs=false,$ys=false,$xe=false,$ye=false
		//pildisuurus ja vajatava konteineri suurus
		if($this->imageObjW > $this->imageObjH){
			$size = $this->imageObjW;  //c konteiner
			//$cheight = $this->imageObjW;
			$dheight = $this->imageObjW; //d sihtkoht
			$dwidth = $this->imageObjH;
		}
		if($this->imageObjW < $this->imageObjH)
		{
			$size = $this->imageObjH;
			$dheight = $this->imageObjW;
			$dwidth = $this->imageObjH;
		}
		if($this->imageObjW == $this->imageObjH)
		{
			$size = $this->imageObjW;
			$dheight = $this->imageObjH;
			$dwidth = $this->imageObjW;
			$cutX=0;
			$cutY=0;
		}
		if (($degrees >= 0) and ($degrees <= 360) )
		{
			// put into container for rotating
			$dst_img = imagecreatetruecolor($size, $size);
			imagecopy($dst_img, $this->imageObj, 0, 0, 0, 0, $this->imageObjW, $this->imageObjH);

			$al = 0;//imagecolorallocate($dst_img, 0, 0, 0);
			//imagecolortransparent ( $dst_img, $al );

			$dst_img = imagerotate($dst_img, $degrees, $al); //php51 ,1
			$this->imageObj = $dst_img;
			$dst_img = imagecreatetruecolor($dwidth, $dheight);


			if(    ( ($degrees==90)&&($this->imageObjW>$this->imageObjH) )   ||   ( ($degrees==270)&&($this->imageObjW<$this->imageObjH) )    )
			{
				imagecopy($dst_img, $this->imageObj, 0, 0, 0, 0, $this->imageObjH,$this->imageObjW);
			}
			elseif ((($degrees == 270) && ($this->imageObjW > $this->imageObjH)) || (($degrees == 90) && ($this->imageObjW < $this->imageObjH)))
			{
				if($this->imageObjW > $this->imageObjH){ $cutX=($this->imageObjW-$this->imageObjH); $cutY=0; $cutwidth=$this->imageObjH; $cutheight=$this->imageObjW;}
				if($this->imageObjW < $this->imageObjH){ $cutX=0; $cutY=($this->imageObjH-$this->imageObjW); $cutwidth=$this->imageObjH; $cutheight=$this->imageObjW;}
				imagecopy($dst_img, $this->imageObj, 0, 0, $cutX, $cutY, $cutwidth, $cutheight);
			} else { $dst_img = $this->imageObj; }

		} else { $dst_img = $this->imageObj; }

		$this->imageObj = $dst_img;

		//
		$this->imageObjW=ImageSX($this->imageObj);
		$this->imageObjH=ImageSY($this->imageObj);
		$this->colorAllocate($this->alphaOne,127,true);
	}//end ImageRotate



	/**
	* not completed
	* //$channelDif=true  maski pildipunkti rgb kanali intensiivsus määrab aluse vastava punkti intensiivsuse
	* //$channelDif=false  maski pildipunkti intensiivsus määrab aluse vastava punkti intensiivsuse
	*
	* @param object $maskImageObj Mask image object ( resource id )
	* @param bool $channelDif
	* @todo  ALL
	*/
	function imageMask($maskImageObj,$channelDif=false)
	{
		$maskImageObjW = imagesx($maskImageObj);
		$maskImageObjH = imagesy($maskImageObj);

		// Compare mask and this image object
		//kumb on laiem
		if($maskImageObjW>$this->imageObjW){}else {}

		//kumb on korgem
		if($maskImageObjH>$this->imageObjH){}else {}

	}




	/**
	* Corp and or resize
	*
	* If $dst_w=false and $dst_h=false then they is same as $src_w and $src_h (Crop)
	* If you set only $dst_w or only $dst_h then other is proportional (Resize)
	*
	* You can crop and resize same time
	*
	* // luuakse uus väljundpilt mõõtudega $dst, kui need on false , siis lõigatu ($src_hw) mõõtudega
	* // kui on antud väljundil ainult laius või kõrgus, siis arvutatakse selle järgi teine külg
	*
	* Usage:
	*<code>
	*  $imagefilepath = SITEIMAGEFILES . $thisimage;
	*  $imo = new imaging;
	*  $imo->imageCreateTCObjFile($imagefilepath);
	*  $imo->imageCropyze( 120,false, false,false,0,0,0,0); //
	*
	*  //  $this->imageCropyze( $dst_w=false,$dst_h=false, $src_w=false,$src_h=false,$dst_x=0,$dst_y=0,  $src_x=0,$src_y=0 )
	*</code>
	* @param int $dst_w
	* @param int $dst_h
	* @param mixed $src_w !INT = ALL
	* @param mixed $src_h !INT = ALL
	* @param int $dst_x TRUE = ALL FALSE = 0
	* @param int $dst_y  TRUE = ALL FALSE = 0
	* @param mixed $src_x TRUE = ALL FALSE = 0
	* @param mixed $src_y TRUE = ALL FALSE = 0
	*/
	function imageCropyze( $dst_w=false,$dst_h=false,    $src_w=false,$src_h=false,
	$dst_x=0,$dst_y=0,            $src_x=0,$src_y=0          )
	{
		$skip=false;
		$p=0;

		//{{{ VALIDATE INPUT	//	SISENDITE KONTROLL

		// $src_x
		if($src_x>$this->imageObjW  or $src_x===true ) { $src_x=$this->imageObjW; }
		elseif($src_w<=0) { $src_x=0; }	// <0 or FALSE or NULL
		else { $src_x=$this->putInRange($src_x,0,$this->imageObjW); }

		// $src_y
		if($src_y>$this->imageObjH or $src_y===true ) { $src_h=$this->imageObjH; }
		elseif($src_h<=0) { $src_y=0; }	// <0 or FALSE or NULL
		else { $src_y=$this->putInRange($src_y,0,$this->imageObjH);  }

		// Default is all image // vaikimisi haaratakse kogu pilt
		if(!is_int($src_w) ) { $src_w=$this->imageObjW; }
		elseif($this->imageObjW < $src_w+$src_x){$src_w=$this->imageObjW; }

		if(!is_int($src_h) ) { $src_h=$this->imageObjH; }
		elseif($this->imageObjH < $src_h+$src_y){$src_y=$this->imageObjH; }


		// by default we crop all image // vaikimisi kropitakse kogu pilt
		if(is_bool($dst_w) ) { $dst_w=$src_w; }
		elseif( $dst_w<=0){$dst_w=1;}
		else { $dst_w= (integer) $dst_w; }

		if(is_bool($dst_h) ) { $dst_h=$src_h; }
		elseif( $dst_h<=0){$dst_h=1;}
		else { $dst_h= (integer) $dst_h; }

		//}}}
		// ~ kui maaratud ainult tulemuse laius või kõrgus on vaikimisi loigatakse tykk originaali küljesuhtega
		if( $dst_w<=0 xor $dst_h<=0 )
		{
			$p=$this->imageProportion( (integer) $dst_w, (integer) $dst_h );
			$dst_w=$p['W'];
			$dst_h=$p['H'];
			$skip =$p['Sk'];
		}

		// siis kui midagi ei tehta ..
		if(    ( $src_x==0 and $src_y==0 and $src_w==$dst_w and $src_h==$dst_h )
				or ( $skip===true )
				)
		{ $skip=true; }

		// kui luuakse sihtpilt
		if($skip===false)
		{
			// now current image is temporary image // kopeerib ja vabastab praeguse pildiobjekti
			$src_img=$this->imageObj;
			$this->imageObj=null;
			$this->imageObj = ImageCreateTrueColor($dst_w,$dst_h) or die( "$dst_w,$dst_h" );

			// teeb pildiobjektiks tüki
			// kui on ka küljesuhte muutus
			if( $src_w<>$dst_w or $src_h<>$dst_h )
			{
				if( function_exists('ImageCopyResampled') )
				{
					@ImageCopyResampled( $this->imageObj,$src_img,   $dst_x,$dst_y,  $src_x,$src_y,  $dst_w,$dst_h,   $src_w,$src_h );
				} else {
					@ImageCopyResized  ( $this->imageObj,$src_img,   $dst_x,$dst_y,  $src_x,$src_y,  $dst_w,$dst_h,   $src_w,$src_h );
				}
			}
			elseif ( $src_w==$dst_w and $src_h==$dst_h  )
			{
				@imagecopy($this->imageObj, $src_img, $dst_x,$dst_y, $src_x,$src_y, $src_w,$src_h);
			}
			// mälu vabastamine
			ImageDestroy($src_img); 
			unset($src_img);
		} //else { }
		// nothing - // ei tehta midagi ja olemasolev pilt jääb


		// nyyd uuendatakse pildiinfot
		$this->imageObjW=ImageSX($this->imageObj);
		$this->imageObjH=ImageSY($this->imageObj);

	}//imageThumb



	/**
	* Get shortish side proportional lenght and aspect ratio
	*
	* // Lühema külje proportsionaalne pikkus ja külgede suhe
	*
	* If you use $ow and $ow then this image W H not used
	* output array 'Sk' is original image aspect ratio
	*
	*<code>
	* $imo_p = $imo->imageProportion( 150,1,300,400);
	* // $imo_p = array (  )
	*</code>
	* @param int $WIDTH_MAX
	* @param int $HEIGHT_MAX
	* @param mixed $ow FALSE = This H; INT other image H
	* @param mixed $oh FALSE = This W; INT other image W
	* @return array array( (int)'W', (int) 'H',(float) 'Sk')
	* @todo maybe not stable.
	*/
	function imageProportion( $WIDTH_MAX=1,$HEIGHT_MAX=1,   $ow=false,$oh=false  )
	{
		$s=1;
		$d=2;
		
		// if this image dimensions // originaalpildi mõõdud
		if    ($ow===false or $oh===false) { 
			$ow = $this->imageObjW;
			if($ow<1) $ow=1;
			$oh = $this->imageObjH; 
			if($oh<1) $oh=1;
		}
		elseif($ow!==false and $oh!==false) {
			$ow= (integer) $ow;
			$oh= (integer) $oh;
		}
		
		// new dimensions
		    if($WIDTH_MAX<1 and $HEIGHT_MAX>1) $WIDTH_MAX=false; // if only H
		elseif($WIDTH_MAX>1 and $HEIGHT_MAX<1) $HEIGHT_MAX=false; // if only W
		elseif($WIDTH_MAX>1 and $HEIGHT_MAX>1);
		elseif($WIDTH_MAX<1 and $HEIGHT_MAX<1) {
					$WIDTH_MAX= 512; //384; // floor( ($ow+4) /2 );
					$HEIGHT_MAX= 512; //384; //floor( ($oh+4) /2 );
		}
		
		if($ow>$oh) $d=0; elseif($ow<$oh) $d=1; else $d=2;
		
		if( $WIDTH_MAX===false) { $d=1; $WIDTH_MAX=$oh;}
		elseif( $HEIGHT_MAX===false) { $d=0; $HEIGHT_MAX=$ow;}
		
		// Actions // tegevused
		switch($d)
		{
		case 0:
			$dst_w = $WIDTH_MAX;
			$dst_h = ($oh*$WIDTH_MAX)/$ow;
			break;
		case 1:
			$dst_w = ($ow*$HEIGHT_MAX)/$oh;
			$dst_h = $HEIGHT_MAX;
			break;
		case 2:
			$dst_w = $ow;
			$dst_h = $oh;
			break;
		}

		// error
		($dst_w<1)?(($ow+4)/2):$dst_w;
		($dst_h<1)?(($oh+4)/2):$dst_h;

		if($ow>$oh) { $s=$ow/$oh; } else { $s=$oh/$ow; }
		
		return array( 'W'=>ceil($dst_w),'H'=>ceil($dst_h),'Sk'=>round($s,2) );
	}

	// bro|fil|obj       //
	/**
	* Output image
	* If selected imagetype unsupported PNG is used 
	*
	*<code>
	* //this send headers and image
	*$imaging_o->outputto_bfo('jpg','bro','image.jpg');
	*</code>
	*
	* @param string $f filetype: gif,jpg,jpeg,jpe,png,bmp,tif,tiff,xbm,wbm
	* @param string $to output where: 'bro' = browser, 'fil' = file, 'obj' = object resource id
	* @param string $fp filepath if $to = 'fil'
	* @return mixed boolean on
	*/
	function outputto_bfo($f='png',$to='bro',$fp='./')
	{
		$f=strtolower($f);
		if( !function_exists( "image$f" ) ) { $f='png'; }
		
		if($to=='obj'){ return $this->imageObj; }

		if($fp=='./' or $fp==''){ $fp .= $this->imageName.'.'.$f; }

		// header('Content-Length: '.$size);
		$cts=array(   'gif'=>'image/gif'
		, 'jpg'=>'image/jpeg','jpe'=>'image/jpeg','jpeg'=>'image/jpeg'
		, 'png'=>'image/png','bmp'=>'image/bmp','tif'=>'image/png','tiff'=>'image/png'
		, 'xbm'=>'image/xbm', 'wbmp'=>'image/vnd.wap.wbmp' );
		$pfu=array(  'gif'=>'gif'
		, 'jpg'=>'jpeg','jpe'=>'jpeg','jpeg'=>'jpeg'
		, 'png'=>'png','bmp'=>'bmp','tif'=>'png','tiff'=>'png'
		, 'xbm'=>'xbm', 'wbmp'=>'wbmp' );
		$p3= array(   'gif'=>''
		, 'jpg'=>','.$this->jpegquality,'jpe'=>','.$this->jpegquality,'jpeg'=>','.$this->jpegquality
		, 'png'=>'','bmp'=>'','tif'=>'','tiff'=>''
		, 'xbm'=>",\$this->xbmForeground", 'wbmp'=>",\$this->wbmpForeground" );

		$return = false;

		$evalexec="
					if( (imagetypes() & ".strtoupper('iMG_'.$f).") or ".strtoupper($f)."=='BMP' )
					{
						switch(\$to)
						{
						case 'bro':
							//header(\"Content-Disposition: attachment; filename=".$this->imageName.'.'.$f."\");
							header(\"Content-type: ".$cts[$f]."\");
							if(\$p3[\$f]==\"\"){ \$return = @image" . $pfu[$f] . "(\$this->imageObj ); }
							else { \$return = @image" . $pfu[$f] . "(\$this->imageObj , '' ".$p3[$f]." ); }
						break;
						case 'fil':
							\$return = @image" . $pfu[$f] . "(\$this->imageObj , '$fp' ".$p3[$f]." );
						break;
						case 'obj':
							\$return = true;
						break;
						}
				}
		";
		eval($evalexec);

		return $return;
	}





} //end class





/**
* pisipildi laius
*/
$GLOBALS['img_thmb_W']=120;
/**
* pisipildi kõrgus
*/
$GLOBALS['img_thmb_H']=120;

/**
* Sample function for demonsttrate usage of the imaging class
*
* @param string $path
* @param bool $isThumb
* @param int $W
* @param int $H
*/
function imageReized($path='',$isThumb=true,$W=0,$H=0)
{
	if(empty($path)){ return false; }

	$imagingobj = new imaging;
	$imagingobj->jpegquality =80;
	$imagingobj->imageCreateTCObjFile($path);

	//Kui pisipildiks
	if($isThumb===true)
	{
		if($W==0)$W=$GLOBALS['img_thmb_W'];
		if($H==0)$H=$GLOBALS['img_thmb_H'];
	} elseif($isThumb===false) {
		$W= (integer) $W;
		if($W<=0){$W=$imagingobj->imageObjW/2;}
		$H= (integer) $H;
		if($H<=0){$H=$imagingobj->imageObjH/2;}
	}
	if(($W==$imagingobj->imageObjW) and ($H==$imagingobj->imageObjH))
	{
		return $imagingobj->outputto_bfo('jpg','bro','imaging2.jpg'); 
	}

	//prop m5lema kylje jargi
	$thumb_prop = $imagingobj->imageProportion( $W,$H );
	//die( $thumb_prop['W'] .' '. $thumb_prop['H'] );
	$imagingobj->imageCropyze( $thumb_prop['W'],$thumb_prop['H'], $imagingobj->imageObjW,$imagingobj->imageObjH,0,0,  0,0 );

	//vari pisipildile
	if($isThumb===true) { $imagingobj->shadowAdd('#B1B1B1','#FFFFFF',5,1,false); }

	//v2ljund
	$imagingobj->outputto_bfo('jpg','bro','imaging2.jpg');
}

?>
Return current item: Imaging