Let us say you have some images and want to watermark those images with some other gif, jpeg, png images or with some plain text on the fly in PHP.
It actually looks tough but it is very simple. Let us take a real time example of profile picture option we have here at Go4Expert.com where if you visit the contact info tab of your profile you will see a code as follow.
And the output will be something like

But actually it is this image

Which converts into

Now let us see how.
PHP 4+ and GD 2.0+.
It loads the file into the PHP script using the GD library and gives us the opportunity to manipulate and/or output the image using our script.
We define variables for color and fonts which we will use to output the final text on the base image.
If we already have an image for the user we should check for last updated time and if it is less than a day we just use the existing image and do not update the image with latest information. This is done to cache the image for a day and is updated every 24 hours.
Next we test for a user uploaded profile picture. If user has uploaded a profile picture we need to use the profile picture in our final image and depending on the uploaded image format we create the profile image from the file and then using imagecopyresampled we merge the two images at the desired locations.
Now we place few strings of user text at desired location.
All done now out output the final image
The above solution can also be used to watermark the images because standard watermarking procedure of editing the image in a photo-editing application is very time consuming and PHP offers better solution.
You can use the above method to loop through an entire directory to watermark all images in one go.
Possibilities are endless.
It actually looks tough but it is very simple. Let us take a real time example of profile picture option we have here at Go4Expert.com where if you visit the contact info tab of your profile you will see a code as follow.
HTML Code:
<A rel="nofollow" HREF="http://www.go4expert.com/member.php?u=1"><IMG SRC="http://www.go4expert.com/share/member1.jpg" WIDTH="120" HEIGHT="90" BORDER="0" ALT="shabbir's Profile at Go4Expert.com"></A>

But actually it is this image

Which converts into

Now let us see how.
Requirements
PHP 4+ and GD 2.0+.
Code
PHP Code:
$im = imagecreatefromjpeg($baseimg);
We define variables for color and fonts which we will use to output the final text on the base image.
PHP Code:
$text_color[0] = imagecolorallocate($im, 255, 255, 0);
$text_color[1] = imagecolorallocate($im, 192, 192, 192);
$text_color[2] = imagecolorallocate($im, 255, 255, 255);
$text_color[3] = imagecolorallocate($im, 255, 255, 255);
$font[0] = DIR .'/images/user/fonts/arialbd.ttf';
$font[1] = DIR .'/images/user/fonts/arialbd.ttf';
$font[2] = DIR .'/images/user/fonts/arialbd.ttf';
$font[3] = DIR .'/images/user/fonts/arialbd.ttf';
PHP Code:
$finalimg = './advprofilepic/member'.$userid.'.jpg';
if(file_exists($finalimg))
{
$cachetime = TIMENOW - 86400;
if($cachetime < filemtime($finalimg))
{
header('Content-type: image/jpg');
readfile($finalimg);
exit;
}
}
PHP Code:
// We have access to the linked image file
if (file_exists($profilepicurl))
{
list($width, $height, $image_type, $attr) = getimagesize($profilepicurl);
$max_width = 32;
$max_height = 32;
if($width > $height)
{
$width = $height;
}
elseif($width < $height)
{
$height = $width;
}
$profileim = imagecreatetruecolor($max_width,$max_height);
$bg_color = imagecolorallocate ($profileim, 0,0,0); //background white
imagefilledrectangle ($profileim, 0, 0, $max_width, $max_height, $bg_color);
switch ($image_type)
{
case 1: $profileim = imagecreatefromgif($userinfo['profilepicurl']); break;
case 2: $profileim = imagecreatefromjpeg($userinfo['profilepicurl']); break;
case 3: $profileim = imagecreatefrompng($userinfo['profilepicurl']); break;
default: trigger_error('Unsupported filetype!', E_USER_WARNING); break;
}
imagecopyresampled($im, $profileim, 5, 35, 0, 0, $max_width, $max_height, $width, $height); // copy empty banner
imagedestroy($profileim);
}
PHP Code:
$text = "Posts at";
if(function_exists('imagettftext'))
{
imagettftext($im, 12, 0, $left, $top, $text_color[0], $font[0], $username);
imagettftext($im, 8, 0, $left, $top+$linespacing, $text_color[1], $font[1], $usertitle);
imagettftext($im, 10, 0, $leftcounter, $topcounter, $text_color[2], $font[2], number_format($posts));
imagettftext($im, 10, 0, $leftcounter, $topcounter + $linespacing, $text_color[3], $font[3], $text);
}
PHP Code:
imagepng($im,$finalimg);
header('Cache-control: max-age=86400');
header('Expires: ' . gmdate('D, d M Y H:i:s', (TIMENOW + 86400)) . ' GMT');
header('Content-disposition: inline; filename=' . $username . '.png');
header('Content-transfer-encoding: binary');
header("Content-type: image/png");
imagepng($im);
imagedestroy($im);
Complete Code
PHP Code:
<?php
$left = 4; //Left text-margin
$top = 15; //text-margin from top
$leftcounter = 44;
$topcounter = 48;
$linespacing = 12;
$baseimg = './images/user/base.jpg'; //full path to empty input image
$finalimg = './advprofilepic/member0.jpg';
$im = imagecreatefromjpeg($baseimg);
$text_color[0] = imagecolorallocate($im, 255, 255, 0);
$text_color[1] = imagecolorallocate($im, 192, 192, 192);
$text_color[2] = imagecolorallocate($im, 255, 255, 255);
$text_color[3] = imagecolorallocate($im, 255, 255, 255);
$font[0] = DIR .'/images/user/fonts/arialbd.ttf';
$font[1] = DIR .'/images/user/fonts/arialbd.ttf';
$font[2] = DIR .'/images/user/fonts/arialbd.ttf';
$font[3] = DIR .'/images/user/fonts/arialbd.ttf';
if($userid <> 0)
{
$finalimg = './advprofilepic/member'.$userid.'.jpg';
if(file_exists($finalimg))
{
$cachetime = TIMENOW - 86400;
if($cachetime < filemtime($finalimg))
{
header('Content-type: image/jpg');
readfile($finalimg);
exit;
}
}
// We have access to the linked image file
if (file_exists($profilepicurl))
{
list($width, $height, $image_type, $attr) = getimagesize($profilepicurl);
$max_width = 32;
$max_height = 32;
if($width > $height)
{
$width = $height;
}
elseif($width < $height)
{
$height = $width;
}
$profileim = imagecreatetruecolor($max_width,$max_height);
$bg_color = imagecolorallocate ($profileim, 0,0,0); //background white
imagefilledrectangle ($profileim, 0, 0, $max_width, $max_height, $bg_color);
switch ($image_type)
{
case 1: $profileim = imagecreatefromgif($userinfo['profilepicurl']); break;
case 2: $profileim = imagecreatefromjpeg($userinfo['profilepicurl']); break;
case 3: $profileim = imagecreatefrompng($userinfo['profilepicurl']); break;
default: trigger_error('Unsupported filetype!', E_USER_WARNING); break;
}
imagecopyresampled($im, $profileim, 5, 35, 0, 0, $max_width, $max_height, $width, $height); // copy empty banner
imagedestroy($profileim);
}
$text = "Posts at";
if(function_exists('imagettftext'))
{
imagettftext($im, 12, 0, $left, $top, $text_color[0], $font[0], $username);
imagettftext($im, 8, 0, $left, $top+$linespacing, $text_color[1], $font[1], $usertitle);
imagettftext($im, 10, 0, $leftcounter, $topcounter, $text_color[2], $font[2], number_format($posts));
imagettftext($im, 10, 0, $leftcounter, $topcounter + $linespacing, $text_color[3], $font[3], $text);
}
}
imagepng($im,$finalimg);
header('Cache-control: max-age=86400');
header('Expires: ' . gmdate('D, d M Y H:i:s', (TIMENOW + 86400)) . ' GMT');
header('Content-disposition: inline; filename=' . $username . '.png');
header('Content-transfer-encoding: binary');
header("Content-type: image/png");
imagepng($im);
imagedestroy($im);
?>
You can use the above method to loop through an entire directory to watermark all images in one go.
Possibilities are endless.


