I find if you are going to create a png image with php's gd libary extension you should tell the browser that your creating a png image. Otherwise you might end up with something bad outputed. So, instead of doing image/jpeg as the header information do a image/png or an image/x-png. Also, I know that the gd libary can't change the file type of an image. If it is read in as a .png it will only be able to be outputed as a png, same with the other formats. I noticed the article said that *.gif support did not work in 2.0+ gd. Yes, it does work. It just doesn't support animated .gif files. It has to be static .gif files.
Now, for a more robust error proof way of reading in the images then you should look towards checking the mime type of he image then do a switch or if then statements to set the proper imagecreatefrom* with the mime type of the image.
I made comments to the listed code example. I know the comments and code isn't 100%, but correct me where you can and help out with this.
call by: watermark.php?photofile=name_of_png_image.png
orginal image need to be bigger then the watermark image
orginal image and watermark image needs to be a .png file type
Either a .htaccesss file or aphache has to be setup to output this .php file as a image file.
//read in the varibles from command line
$photofile = $_GET['photofile'];
/* read the watermark image into memory. This would be a good place to detect the mime of the photofile and setup a switch to create the rigth type of image from it. */
$watermark = imagecreatefrompng('watermark.png');
/* get the width and height of the watermark image. */
list($watermark_width,$watermark_height) = getimagesize('watermark.png');
/* read in the photofile into memory. Another good place to setup a mime type switch to create the right image from the detected mime type. */
$image = imagecreatefrompng($photofile);
/* this does the x,y position of the watermark need to cover the orginal image */
list($img_w,$img_h) = getimagesize($photofile);
$dest_x = $img_w - $watermark_width - 5;
$dest_y = $img_h - $watermark_height - 5;
/* save the transparentcy of the orginal image. */
/* copy the watermarked image onto the orginal image. */
/* output the image. Great place to setup a mime switch to output the correct content type message */
header("Content-Disposition: filename= " . $photofile);
//free up the memory used