Frank Moricz


Web Portfolio and Art Gallery

Magic made with caffeine and a keyboard.

Watermarking images with PHP

This morning I wanted to start hacking away on my Texture website, and to do so, I had to consider how images will be displayed.  Since the images are the things for sale, how do you display them but restrict usage of them?

So, we're gonna need a watermark.  Here's what I went with - a basic transparent png with the word sample:

So, we're going to need to do a few unique things here to make a good and usable thumbnail.  Im aiming for a 300x300 image size.  Here is the final code, and then i'll step through it.

function AddWatermark($source, $imageName) {
    //Create a Square watermarked image for display on page.
    //Ensure original file names and locations are never client-side
      $dimensions = 300;
      //Grab watermark
      $watermark=imagecreatefrompng('images/SampleWatermark.png');
      //Source and original dimensions
      $image_size=getimagesize($source);
      //Create blank images
      $image=imagecreatetruecolor($image_size[0], $image_size[1]);
      $image2=imagecreatetruecolor($dimensions,$dimensions);
      //Fill source image, resize a square portion down to 300x300
      $image=imagecreatefrompng($source);
      imagecopyresized($image2, $image,0,0,0,0,$dimensions,$dimensions,$image_size[0],$image_size[0]);
      //Create blank images for working and output
      $cut = imagecreatetruecolor($dimensions,$dimensions);
      $output = imagecreatetruecolor($dimensions,$dimensions);
      //Copy the layers over individually to preserve alpha
      imagecopy($cut, $image2, 0, 0, 0, 0, $dimensions, $dimensions);
      imagecopy($cut, $watermark, 0, 0, 0, 0, $dimensions, $dimensions);
      //Merge layers and save file
      imagecopymerge($output, $cut, 0, 0, 0, 0, $dimensions, $dimensions, 100);
      imagepng($output, $imageName);
  };

So here's the deal -- PHP can easily merge images, but it gets really weird with alpha channels and my first experiments were... not great.

We also want to take a "good", square picture of a texture and then overlay on to of THAT, not just grab any 300x300 section of an image.

So, step by step:

  • Set the dimensions of the watermarked, final target - 300px.
  • Assign the location of that watermarked image to a variable
  • Get the dimensions of the source (much larger) image
  • Create 2 blank slates for PHP to work with.  One of these is the original size of the source image, the other one will be the size we want.
    • We're going to use the fact that textures to be used here will either be square or taller than they are wide
  • Take a square from the source image, as large as possible, and resize it down to target size, placing that on our other blank slate.
  • At this point, we have 2 things we're still working with - the watermark image (which was already the right size), and the newly fashioned resized image.  Now we can combine them.
  • We're going to make 2 more blank slates
  • Using the imagecopy function we fill 1 blank slate with the output from above (non transparent layer first), and it preserves the alpha channels correctly.
  • Now we can use imagecopymerge to create a final output of those 2 layers merged together.
  • Save it to a folder (ensure permissions allow this), and we're good to go!