Articles: 843 | Categories: 148   
   
   
Home Articles Contact Us
 
 
 
 
Watermark Images (0 Comments)
Admin: Posted Date: April 4, 2010

The following code sample demonstrates the use of GD library to watermark images on the fly. The method demonstrated here to watermark an uploaded image is to overlay the original image with another image, preferably a transparent PNG image.

Watermark Your Images

The following code sample demonstrates the use of GD library to watermark images on the fly. The method demonstrated here to watermark an uploaded image is to overlay the original image with another image, preferably a transparent PNG image.

PHP provides a rich set of functions to create and alter images on the fly. These functions require the GD library, which is bundled with PHP since version 4.3.

The Complete Example

The working code sample consists of the following items:

  1. HTML form that posts an image to the PHP script
  2. The PHP Script
  3. The Watermark Image
HTML Form

The HTML form needs a file upload element: <input type="file">. You must also specify the correct encoding type: enctype="multipart/form-data" for the form.

<form action="watermark-image.php" method="post" enctype="multipart/form-data">
Select a file to upload for processing<br>
<input type="file" name="File1"><br>
<input type="submit" value="Submit File">
</form>
The PHP Script

The following code handles the file upload and performs the image processing.

<?php
//--------------------------------
// CREATE WATERMARK FUNCTION
//--------------------------------
define( 'WATERMARK_OVERLAY_IMAGE', 'watermark.png' );
define( 'WATERMARK_OVERLAY_OPACITY', 50 );
define( 'WATERMARK_OUTPUT_QUALITY', 90 );
function create_watermark( $source_file_path, $output_file_path )
{
list( $source_width, $source_height, $source_type ) = getimagesize( $source_file_path );
if ( $source_type === NULL )
{
return false;
}
switch ( $source_type )
{
case IMAGETYPE_GIF:
$source_gd_image = imagecreatefromgif( $source_file_path );
break;
case IMAGETYPE_JPEG:
$source_gd_image = imagecreatefromjpeg( $source_file_path );
break;
case IMAGETYPE_PNG:
$source_gd_image = imagecreatefrompng( $source_file_path );
break;
default:
return false;
}
$overlay_gd_image = imagecreatefrompng( WATERMARK_OVERLAY_IMAGE );
$overlay_width = imagesx( $overlay_gd_image );
$overlay_height = imagesy( $overlay_gd_image );
imagecopymerge(
$source_gd_image,
$overlay_gd_image,
$source_width - $overlay_width,
$source_height - $overlay_height,
0,
0,
$overlay_width,
$overlay_height,
WATERMARK_OVERLAY_OPACITY
);
imagejpeg( $source_gd_image, $output_file_path, WATERMARK_OUTPUT_QUALITY );
imagedestroy( $source_gd_image );
imagedestroy( $overlay_gd_image );
}
//--------------------------------
// FILE PROCESSING FUNCTION
//--------------------------------
define( 'UPLOADED_IMAGE_DESTINATION', 'originals/' );
define( 'PROCESSED_IMAGE_DESTINATION', 'images/' );
function process_image_upload( $Field )
{
$temp_file_path = $_FILES[ $Field ][ 'tmp_name' ];
$temp_file_name = $_FILES[ $Field ][ 'name' ];
list( , , $temp_type ) = getimagesize( $temp_file_path );
if ( $temp_type === NULL )
{
return false;
}
switch ( $temp_type )
{
case IMAGETYPE_GIF:
break;
case IMAGETYPE_JPEG:
break;
case IMAGETYPE_PNG:
break;
default:
return false;
}

$uploaded_file_path = UPLOADED_IMAGE_DESTINATION . $temp_file_name; $processed_file_path = PROCESSED_IMAGE_DESTINATION . preg_replace( '/\\.[^\\.]+$/', '.jpg', $temp_file_name ); move_uploaded_file( $temp_file_path, $uploaded_file_path ); $result = create_watermark( $uploaded_file_path, $processed_file_path ); if ( $result === false ) { return false; } else { return array( $uploaded_file_path, $processed_file_path ); } } //-------------------------------- // END OF FUNCTIONS //-------------------------------- $result = process_image_upload( 'File1' ); if ( $result === false ) { echo '<br>An error occurred during file processing.'; } else { echo '<br>Original image saved as <a href="' . $result[ 0 ] . '" target="_blank">' . $result[ 0 ] . '</a>'; echo '<br>Watermarked image saved as <a href="' . $result[ 1 ] . '" target="_blank">' . $result[ 1 ] . '</a>'; } ?>
The Watermark Image

The watermark image should be in one of the following recommended formats:

  • PNG-8 (recommended)
    Colors: 256 or less
    Transparency: On/Off
  • GIF
    Colors: 256 or less
    Transparency: On/Off
  • JPEG
    Colors: True color
    Transparency: n/a

The imagecopymerge function does not properly handle the PNG-24 images; it is therefore not recommend.

If you are using Adobe Photoshop to create watermark images, it is recommended that you use "Save for Web" command with the following settings:

  • File Format: PNG-8, non-interlaced
  • Color Reduction: Selective, 256 colors
  • Dithering: Diffusion, 88%
  • Transparency: On, Matte: None
  • Transparency Dither: Diffusion Transparency Dither, 100%

How it Works

The function relies on the imagecopymerge function available in GD library. This function copies a rectangular region from one image onto the other. The important thing is that this function allows you to specify the opacity of the image that is rendered on the destination image.

Example Output

Example 1: Original Image

Example 1: Watermarked image showing four different combinations of alignment and opacity

 

Example 2: Original Image

Example 2: Watermarked image showing four different combinations of alignment and opacity

Variations of the Function

The example above will place the watermark image on the lower-right corner of the original image with 50% opacity. To experiment with other alignment options, you can modify the line containing imagecopymerge as follows:

<?php
//--------------------------------
// ALIGN TOP, LEFT
//--------------------------------
imagecopymerge(
$source_gd_image,
$overlay_gd_image,
0,
0,
0,
0,
$overlay_width,
$overlay_height,
WATERMARK_OVERLAY_OPACITY
);
//--------------------------------
// ALIGN TOP, RIGHT
//--------------------------------
imagecopymerge(
$source_gd_image,
$overlay_gd_image,
$source_width - $overlay_width,
0,
0,
0,
$overlay_width,
$overlay_height,
WATERMARK_OVERLAY_OPACITY
);
//--------------------------------
// ALIGN BOTTOM, RIGHT
//--------------------------------
imagecopymerge(
$source_gd_image,
$overlay_gd_image,
$source_width - $overlay_width,
$source_height - $overlay_height,
0,
0,
$overlay_width,
$overlay_height,
WATERMARK_OVERLAY_OPACITY
);
//--------------------------------
// ALIGN BOTTOM, LEFT
//--------------------------------
imagecopymerge(
$source_gd_image,
$overlay_gd_image,
0,
$source_height - $overlay_height,
0,
0,
$overlay_width,
$overlay_height,
WATERMARK_OVERLAY_OPACITY
);
?>

Limitations of the Script

  • The example currently supports GIF, JPEG and PNG file handling. Additional image type support can be added rather easily.
  • The example does not generate unique file names and therefore overwrites existing uploaded or thumbnail images.
  • The example does not show any error messages. All "return false" need to be replaced by appropriate error handling.
  • 256 color watermark images with transparency often have visible artifacts around the edges after rendering.
  • 24-bit PNG watermark images are not rendered properly.
  • Additional watermark alignment options are not discussed. I am leaving that as an exercise. FYI, it is as simple as dividing a few numbers by 2.

 

 
 
Add a Comment:
 
(You must be signed in to comment on an article. Not a member? Click here to register)
   
Title:

Comments: