Image Watermarking/ Copyright with GD

I was wondering if anyone has made is possible to add a pre-defined copyright notice to all the images generated by Zenphoto using GD? I would love to have this feature. If anyone could lend a hand, I would much appreciate it.

Thanks,
Nathan
«13

Comments

  • Here would be a pretty good start.. but I dont think it is in the plans for ZenPhoto for a little while.

    http://www.sitepoint.com/article/watermark-images-php
  • nathan Member
    Trisweb, (or anyone else who knows it inside out), can you tell me where I should look at putting the watermarking function, as the images are generated on the fly, it is not as though we are dealing with fixed files here.

    I am a little confused, so if anyone could clear it up, I would appreciate it.
  • trisweb Administrator
    All image processing is done in i.php, so that's where you'd want to add the watermarks. It'd actually be very easy to do, pretty much how that link describes it.
  • nathan Member
    Okay. I knew that I needed to play around with i.php (and zen_config.php, but I'll get to that), but, where exactly, and how many times to I need to call the function? I notice that there are 3 different ways in which i.php returns an image:
    1. If there are no parameters specified,
    2. If the requested image is the same size or smaller than the original,
    3. and if the image was cropped.
    Does that mean I have to run the function on all of those outputs?

    Also, is it as simple as adding: `$conf['perform_watermark'] = true;` in the zen_config.php file, setting the new variable at the top of i.php (just for convenience) and the adding a simple conditional statement to determine if the watermark will actually take place? I might one day want to turn this off, and I would rather not have to edit the code. It is a much nicer way of doing it I think. I understand that I would need to clear the cache if I changed the setting, for it to take effect on existing images, but that is fine.

    Any more help would be much appreciated. I am really tring to understand the workings of i.php, there is still a bit to learn and this isn't THAT easy for me.

    Thanks,
    Nathan
  • trisweb Administrator
    Yep, that sounds great.

    You only need to do it once to the final image reference, right before the imagejpeg call.

    If you actually want to be using this for a while, I highly recommend getting the latest code from SVN (You can get there through the development section of the wiki). It's got quite a few new features for the next version like custom crops. You'll still do the same thing though, just right before imagejpeg, add your watermark.

    i.php is probably the most confusing part of zenphoto... not too bad though :) It's better in the latest code, I cleaned it up quite a bit and added lots of good comments.
  • nathan Member
    I've got the latest SVN, WITH the crops (I asked for it, remember :P ).

    Thanks. I'll give it a go now and see how it turns out. Thanks for your help (again).
  • nathan Member
    Didn't work for me. I can't be sure i did it correctly, but i.php stopped generating images altogether which to me, is a sure sign I broke something.

    How about this. A little more help (i.e., show me what [exactly] to put where [exactly]) and I donate a little more to zenphoto fund for your time.

    I had all the cropping stuff set up for the desktops/ wallpaper site I am working on, but it cut out the copyright notices on the images (we could never be sure where to put them), so we need to use PHP and put in the bottom corner when we are done hacking them to pieces.

    Any more help would be great.
  • nathan Member
    Here is where I am getting stuck: (i think)
    What do I actually use for the image value in this - `$image = imagecreatefromjpeg($_GET['src']);`? Is it - `$newfile`?

    This is the bottom end of my i.php file, to give you an idea where I am at, or getting it wrong:
    ` // Create the cached file (with lots of compatibility)...

    touch($newfile);

    //-- watermarking

    $watermark = imagecreatefrompng('watermark.png');

    $watermark_width = imagesx($watermark);

    $watermark_height = imagesy($watermark);

    $wimage = imagecreatetruecolor($watermark_width, $watermark_height);

    $wimage = imagecreatefromjpeg($newfile]);

    $size = getimagesize($newfile);

    $dest_x = $size[0] - $watermark_width - 5;

    $dest_y = $size[1] - $watermark_height - 5;

    imagecopymerge($wimage, $watermark, $dest_x, $dest_y, 0, 0, $watermark_width, $watermark_height, 100);

    imagedestroy($watermark);

    $newfile = $wimage;

    //-- /watermarking

    imagejpeg($newim, $newfile, $quality);

    chmod($newfile,0644);

    imagedestroy($newim);

    imagedestroy($im);

    }

    }

    // ... and redirect the browser to it.

    header("Location: " . PROTOCOL . "://" . $_SERVER['HTTP_HOST'] . WEBPATH . "/cache$newfilename");

    ?>`

    Sorry for the double/triple posting. I am trying to do it myself, and learn the workings of i.php.

    Thanks for your patience (with me).

  • trisweb Administrator
    Quite a few syntax errors in there... whew.

    Alright, lemme think...

    //-- watermarking
    $watermark = imagecreatefrompng('watermark.png');
    $watermark_width = imagesx($watermark);
    $watermark_height = imagesy($watermark);
    $dest_x = $neww - $watermark_width - 5;
    $dest_y = $newh - $watermark_height - 5;
    imagecopymerge($newim, $watermark, $dest_x, $dest_y, 0, 0, $watermark_width, $watermark_height, 100);

    imagedestroy($watermark);

    //-- /watermarking

    Yeah, I think that should work. Hasn't been tested though, so come back if you have problems. It's a lot simpler than you were trying to do though.... just make an image from the watermark, get some positions, and merge it onto the existing image ($newim). :)
  • nathan Member
    wow.

    It works (perfectly). Thank you so much for your help and time.

    As I said I would, when I get home this evening, I will put another donation into the zenphoto fund.

    I really appreciate this. It works really well, and it didn't slow down image generation by that much, which is a plus.
  • nathan Member
    The code you posted works, but, through no error in your code, the overlayed image look terrible.

    I think it is because I am using images with white text over a tranparent background. While I am using PNG-8 formatted files (as the article suggests), I still think it is the transparency that is the issue.

    Can you suggest a way around this? I found the following at php.net, that looks like it will do the job, but I have no idea how to use it, how it will work with what we have at present, so I will put it here (first reply/comment on this page): http://au3.php.net/manual/en/function.imagecopymerge.php
  • nathan Member
    I could just print text to the image, but I don't know how to do that either! As it is a opyright notice, it could be easier.
  • trisweb Administrator
    Use an alpha-transparent PNG with anti-aliased edges. In fact, usually watermarks are partly transparent anyway... Fireworks or Photoshop can do that, and the GD library should be able to merge them just fine.
  • nathan Member
    I used an alpha-transparent PNG with anti-aliased edges, with file format PNG-8, and it still looks rubbish. I think it is because the font is small/ thin. Or GD is not as nice as I would have thought.

    You can see the output of one watermark run here:
    http://server.skoap.com/zen.jpg

    I think having GD write directly to the file is looking nice.
  • trisweb Administrator
    Well, imagecopymerge is probably the wrong function to use for true alpha-PNG overlay... I'm sure you could look it up and see.

    If the text works though, cool.
  • nathan Member
    Just to let anyone else know (if someone is interested in the same process later), that to get this working working with png-24 formated image that supports antialiasing and alpha transparency, you need add/change the following.

    `imagealphablending($watermark, false);

    imagesavealpha($watermark, true);`

    Also, you need to use `imagecopy` instead of `imagecopymerge`.

    Thanks everyone for there help.
  • Nathan, how about summarizing this info and putting it in the wiki under the Hacks section? Others may find it helpful.
  • nathan Member
    Sounds like an idea. I will get to it this afternoon.
  • Nathan, did you ever get to it?
  • Skwid Member
    Hey everyone,

    I did my 'watermarking' my own way ! Using text rather than images. This way, the text can be easily changed by editing the setting in zp-config.php, and there is no need to create an image.

    You can see it here (just get to an image)
    http://test.lostocean.net/zp/

    The code calculates the text color based on the average color of the area that is underneath !
  • trisweb Administrator
    Looks pretty cool Skwid, think you could make it transparent and anti-aliased?

    If you want, bundle it up and submit a patch at http://bugs.zenphoto.org.
  • In case anyone wanted to see it in action, I have a zenphoto implementation up at http://www.photosbydaisy.com/zenphoto which is utilizing Skwid's watermarking function.

    Thinkdreams
  • Skwid Member
    Hum trisweb, I'm not sure if i can make transparent text using GD functions, plus it would be hard to read it ...

    By the way, I wrote you an email, but never had an answer. If you didn't have time that's fine, but if you didn't get it, please tell me so I can resend it.
  • This might do the trick:

    http://www.phpbuilder.com/snippet/download.php?type=snippet&id=68

    I haven't had a chance to try it yet though. It solves the different font thing we were talking about the other night Skwid.
  • Skwid Member
    Ok, I got the watermarking working with a transparent PNG made from custom text, font, color, whatever :)

    You can see it in action at the usual URL:

    http://test.lostocean.net/zp

    This is color transparency, i still need to work on alpha transparency.
    I still need to polish it a little.. but it works !
  • nathan Member
    Oh... Crap. I forgot to upload the article. Gimmie a sec and I will do it now.

    I use images, but the script handles alpha transparency, anti-aliasing and png-24 formatted images (the big plus for quality).
  • nathan Member
    Okay. First of all, sorry for being late. I completely forgot about it.

    Here is what needs to be done. For ease of configuration, there are some changes to the zp-config.php file AS WELL as the i.php file. I will try and step it out with easy instructions, but if I am unclear on anything, please let me know. This will eventually be the wiki page.

    1. We will add the extra variables to the zp-config.php and get that out of the way.

    `

    // turn the watermarking on and off

    $conf['perform_watermark'] = true;

    // the image (png-24) in the zen/images/ directory

    $conf['watermark_image'] = "images/watermark.png";

    `

    You can add those anywhere ABOVE the line that says:
    `

    /** Do not edit below this line. **/

    /**********************************/

    `

    2. Put the variables (the rest seem to be up there) at the top of the i.php file (for convenience).

    `

    $perform_watermark = zp_conf('perform_watermark');

    $watermark_image = zp_conf('watermark_image');

    `

    3. Add the watermarking code to the i.php file. It needs to go (as of 1.0.3) in at about line 213, just before the `// Create the cached file (with lots of compatibility)...`

    `

    //-- watermarking

    if ($perform_watermark == true) {

    $watermark = imagecreatefrompng($watermark_image);

    imagealphablending($watermark, false);

    imagesavealpha($watermark, true);

    $watermark_width = imagesx($watermark);

    $watermark_height = imagesy($watermark);

    // Position Overlay in Bottom Right

    $dest_x = imagesx($newim) - $watermark_width;

    $dest_y = imagesy($newim) - $watermark_height;

    imagecopy($newim, $watermark, $dest_x, $dest_y, 0, 0, $watermark_width, $watermark_height);

    imagedestroy($watermark);

    }

    //-- /watermarking

    `

    That is it. Make sure you put the image in the `zen/images/` directory and it will work.

    This WILL also add the watermark to the thumbs. To turn that off, add this line in the thumbnailing part og the `i.php` file (about line 62). Right after the `$thumb = true;`.

    `$perform_watermark = false;`

    Is that wiki worthy?

  • works good for me nathan. the image is a 50% opacity .png created with a text font in photoshop.

    http://www.thinkdreams.com/devzp/scenery/IMG_3280.JPG
  • nathan Member
    Great.

    I'll tidy up the text/ grammar and add it to the wiki.
  • Very nice solution to watermarking.

    The only problem that I have with this hack is that it will only work for those themes which use values set in zp-config.php because those themes use the getImageThumb() and printImageThumb() functions. For both of my themes, I never used those because I wanted to basically "hard-code" (i.e. getCustomImageURL()) the sizes of the thumbnails. In order to get it to work with that function, I'll have to do some major work with i.php and even classes.php.

    Also, I'd like to make a suggestion to your code.
    Instead of having you copy & paste code in three different areas of i.php, just copy and paste the following into i.php "at about line 213, just before the `// Create the cached file (with lots of compatibility)`"

    `////////////////////////////////////////////////////////////////////////////////

    // Watermark Hack

    ////////////////////////////////////////////////////////////////////////////////

    $perform_watermark = zp_conf('perform_watermark');

    $watermark_image = zp_conf('watermark_image');

    if ($perform_watermark == true && $thumb == false) {

    $watermark = imagecreatefrompng($watermark_image);

    imagealphablending($watermark, false);

    imagesavealpha($watermark, true);

    $watermark_width = imagesx($watermark);

    $watermark_height = imagesy($watermark);

    // Position Overlay in Bottom Right

    $dest_x = imagesx($newim) - $watermark_width;

    $dest_y = imagesy($newim) - $watermark_height;

    imagecopy($newim, $watermark, $dest_x, $dest_y, 0, 0, $watermark_width, $watermark_height);

    imagedestroy($watermark);

    }

    ////////////////////////////////////////////////////////////////////////////////`

    This code also takes care of the fact that it's a thumbnail.

Sign In or Register to comment.