Location: PHPKode > scripts > twzWatermark > twzWatermark.class.php
<?php
/*
    twzWatermark.class.php - image watermark v0.1
    
    Copyright © 2007
    All code in this file and associated files is copyright 
    © tweezy.net.au unless otherwise noted. 
    For enquiries please contact hide@address.com
    
    Written for PHP4 19/3/07
    based on example at http://php.net/manual/en/function.imagecopymerge.php (Steve 24-May-2005 04:03)
    _mergetext adapted from http://www.phpjabbers.com/put-watermark-on-images-using-php-php20.html
    
    
    USAGE:
    ------
    Examples showing how to use this class are included with this download.
    
    Class constructor
        $SourceFile .... either filepath to a jpg, gif or png image, or an image resource. 
                         The watermark will be applied to this image.
        $Watermark  .... either filepath to a png image (with eg 30% transparency) to be applied 
                         to the source image, or line of text to be applied to the source image.

    SetTextFont()
        $FontName ...... name of ttf to use
        $Size  ......... font size in pixels
        $Colour ........ text colour; hex string or rgb array (default='000'=black)
        $Angle ......... angle of text in degrees (default=0)

    SetTextShadow()
        $Colour ........ shadow colour; hex string or rgb array
        $Offset ........ pixel offset (default=1)

    SetPosition()
        $Xpos .......... see comment in SetPosition() function
        $Ypos .......... see comment in SetPosition() function

    GetImage()
        $DestFilename .. If numeric zero or not specified, GetImage() will return the image resource 
                         for further processing in PHP.
                         If an empty string, the image will be returned to the browser.
                         Otherwise, will try to save the image to the pathname in $DestFilename.


    You can also pre-define a constant WATERMARK_MARGIN (or separate WATERMARK_MARGIN_X and WATERMARK_MARGIN_Y) 
    to adjust the distance in px from edge of image (default is 5)

*/
	
class twzWatermark
{
function twzWatermark($SourceFile, $Watermark)
	{
	// $Watermark is a string - either a filespec (png) or text to display
	
	if(!is_resource($SourceFile) and !file_exists($SourceFile)) $this->_error("Source file $SourceFile not found!");
	if(''==$Watermark)  $this->_error("Watermark not specified!");
	
	// get resource for base image..
	if(is_resource($SourceFile))
		{
		$this->SourceType = 'png';
		$this->BaseImage = $SourceFile;
		}
	else
		{
		$this->SourceType = strtolower(substr($SourceFile, -3));
		switch($this->SourceType) 
			{
			case('gif'): $this->BaseImage = imagecreatefromgif($SourceFile); break;
			case('png'): $this->BaseImage = imagecreatefrompng($SourceFile); break;
			default: $this->BaseImage = imagecreatefromjpeg($SourceFile);
			}
		}
		
	// get dimensions..
	$this->BaseWidth = imageSX($this->BaseImage);
	$this->BaseHeight= imageSY($this->BaseImage);
	
	// for a gif, upsample to a truecolor image..
	if($this->SourceType == 'gif') 
		{
		$tempimage = imagecreatetruecolor($this->BaseWidth, $this->BaseHeight);
		imagecopy($tempimage, $this->BaseImage, 0, 0, 0, 0, $this->BaseWidth, $this->BaseHeight);
		$this->BaseImage = $tempimage;
		}
	
	if(file_exists($Watermark))
		{
		// get resource for watermark image..
		$this->WatermarkImage = imagecreatefrompng($Watermark);
		imageAlphaBlending($this->WatermarkImage, false);
		imageSaveAlpha($this->WatermarkImage, true);
		// get dimensions..
		$this->WatermarkWidth = imageSX($this->WatermarkImage);
		$this->WatermarkHeight= imageSY($this->WatermarkImage);
		$this->DoImage=true;
		}
	else
		{
		//text string only..
		$this->WatermarkText=$Watermark;
		// default font settings..
		$this->FontName = 'arial.ttf';
		$this->FontSize = 10;
		$this->FontAngle = 0;
		$this->FontColor = $this->_hex2rgb('#000000',true);
		$this->DoImage=false;
		}
	
	// default position..
	$this->SetPosition('LT');
	}

function SetPosition($Xpos, $Ypos='')
	{
	/* Determine X, Y position for watermark image (not as useful for text?)
	* 
	* Accepts pixel values, or first letter of: Top, Bottom, Left, Right, Centre, Middle
	* 
	* 	both parameters .. .. .. .. .. 10,50	10, 'B'
	* 	one parameter (comma-sep) . .. '10,50'	'L,100'
	* 	one parameter (shortcut) .. .. 'lt'		'br'	'cm'
	*/
	if(!defined('WATERMARK_MARGIN')) define('WATERMARK_MARGIN',5);
	if(!defined('WATERMARK_MARGIN_X')) define('WATERMARK_MARGIN_X',WATERMARK_MARGIN);
	if(!defined('WATERMARK_MARGIN_Y')) define('WATERMARK_MARGIN_Y',WATERMARK_MARGIN);
	
	$Xpos=str_replace('M','C',strtoupper($Xpos)); 
	$Ypos=str_replace('M','C',strtoupper($Ypos)); 
	
	if(''==$Ypos)
		{
		// X and Y are both in $Xpos string..
		if(strpos($Xpos,','))
			{
			list($Xpos,$Ypos)=explode(',',$Xpos);
			}
		else switch($Xpos)
			{
			case 'TL': case 'LT': $Xpos='L'; $Ypos='T'; break;
			case 'TR': case 'RT': $Xpos='R'; $Ypos='T'; break;
			case 'BL': case 'LB': $Xpos='L'; $Ypos='B'; break;
			case 'BR': case 'RB': $Xpos='R'; $Ypos='B'; break;
			case 'TC': case 'CT': $Xpos='C'; $Ypos='T'; break;
			case 'BC': case 'CB': $Xpos='C'; $Ypos='B'; break;
			case 'CR': case 'RC': $Xpos='R'; $Ypos='C'; break;
			case 'CL': case 'LC': $Xpos='L'; $Ypos='C'; break;
			case 'CC': $Xpos='C'; $Ypos='C'; break;
			}
		}
	
	
	if($this->DoImage)
		{
		$MarkWidth=$this->WatermarkWidth;
		$MarkHeight=$this->WatermarkHeight;
		}
	else
		{
		// this is a bit dodgy - especially with angled text..
		$TextBox = imagettfbbox($this->FontSize, $this->FontAngle, $this->FontName, $this->WatermarkText);
		$MarkWidth =max($TextBox[0],$TextBox[2],$TextBox[4],$TextBox[6]) - min($TextBox[0],$TextBox[2],$TextBox[4],$TextBox[6]);
		$MarkHeight=max($TextBox[1],$TextBox[3],$TextBox[5],$TextBox[7]) - min($TextBox[1],$TextBox[3],$TextBox[5],$TextBox[7]);
		}
	
	if(is_numeric($Xpos)) { $this->Xpos=$Xpos; }
	else
		{
		switch($Xpos)
			{
			case 'L': $this->Xpos = WATERMARK_MARGIN_X; break;
			case 'R': $this->Xpos = $this->BaseWidth - $MarkWidth - WATERMARK_MARGIN_X; break;
			default:  $this->Xpos = $this->BaseWidth / 2 - $MarkWidth / 2;
			}
		}

	if(is_numeric($Ypos)) { $this->Ypos=$Ypos; }
	else
		{
		switch($Ypos)
			{
			case 'T': $this->Ypos = WATERMARK_MARGIN_Y; break;
			case 'B': $this->Ypos = $this->BaseHeight - $MarkHeight - WATERMARK_MARGIN_Y; break;
			default:  $this->Ypos = $this->BaseHeight / 2 - $MarkHeight / 2;
			}
		}
	}


function SetTextFont($FontName, $Size, $Colour='000', $Angle=0)
	{
	$this->FontName = $FontName;
	$this->FontSize = $Size;
	$this->FontAngle = $Angle;
	
	if(is_string($Colour)) $Colour=$this->_hex2rgb($Colour,true);
	$this->FontColor = $Colour;
	}

function SetTextShadow($Colour, $Offset=1)
	{
	if(is_string($Colour)) $Colour=$this->_hex2rgb($Colour,true);
	$this->ShadowColor = $Colour;
	$this->Offset = $Offset;
	}

function _hex2rgb($HexCol, $ReturnAsArray=false) // not exhaustively tested yet!
	{ 
	if('#'==substr($HexCol,0,1)) $HexCol=substr($HexCol,1); 
	if(3==strlen($HexCol)) $HexCol=substr($HexCol,0,1).substr($HexCol,0,1).substr($HexCol,1,1).substr($HexCol,1,1).substr($HexCol,2,1).substr($HexCol,2,1); 
	if(6==strlen($HexCol))
		{ $r = hexdec(substr($HexCol, 0, 2)); $g = hexdec(substr($HexCol, 2, 2)); $b = hexdec(substr($HexCol, 4, 2));  }
	else
		{ $r=0; $g=0; $b=0; }
	if($ReturnAsArray) return array($r, $g, $b); else return "$r,$g,$b"; }

function _mergeimage()
	{
	imagecopy($this->BaseImage, $this->WatermarkImage, $this->Xpos, $this->Ypos, 0, 0, $this->WatermarkWidth, $this->WatermarkHeight);
	$this->ImageDone=true;
	}

function _mergetext()
	{
	//shadow text..
	if(isset($this->ShadowColor))
		{
		$ShadowColor = imagecolorallocate($this->BaseImage, $this->ShadowColor[0], $this->ShadowColor[1], $this->ShadowColor[2]);
		imagettftext($this->BaseImage, $this->FontSize, $this->FontAngle, $this->Xpos - $this->Offset, $this->Ypos + $this->Offset, $ShadowColor, $this->FontName, $this->WatermarkText);
		}
	// main text..
	$TextColor = imagecolorallocate($this->BaseImage, $this->FontColor[0], $this->FontColor[1], $this->FontColor[2]);
	imagettftext($this->BaseImage, $this->FontSize, $this->FontAngle, $this->Xpos, $this->Ypos, $TextColor, $this->FontName, $this->WatermarkText);
	}

function GetImage($DestFilename=0)
	{
	// Add watermark..
	if($this->DoImage)  $this->_mergeimage();
	else 				$this->_mergetext();
	
    if(is_numeric($DestFilename))
        { return $this->BaseImage; } // return the image resource (added 29/7/09)
    
	// Send or save final image..
	switch($this->SourceType) 
		{
		case 'png':
			if($DestFilename=='')
				{
				header("Content-type: image/png");
				imagepng ($this->BaseImage);
				}
			else imagepng ($this->BaseImage, $DestFilename);
			break;

		default: // gif or jpg
			if($DestFilename=='') 
				{
				header("Content-type: image/jpg");
				imagejpeg ($this->BaseImage);
				}
			else imagejpeg ($this->BaseImage, $DestFilename);
		}         
   imagedestroy($this->BaseImage);
   imagedestroy($this->WatermarkImage);
	}

function _error($Message)
	{
	die("<br /><br />$Message<br />");
	}
} // end class twzWatermark

?>
Return current item: twzWatermark