Jump to content

Extending the ImageField with a watermark option


formmailer
 Share

Recommended Posts

Hi!

I found the following code snippets on php.net and figured that it would be a nice add on to the ImageField.

Example #1 Adding watermarks to images using alpha channels

<?php
// Load the stamp and the photo to apply the watermark to
$stamp = imagecreatefrompng('stamp.png');
$im = imagecreatefromjpeg('photo.jpeg');

// Set the margins for the stamp and get the height/width of the stamp image
$marge_right = 10;
$marge_bottom = 10;
$sx = imagesx($stamp);
$sy = imagesy($stamp);

// Copy the stamp image onto our photo using the margin offsets and the photo 
// width to calculate positioning of the stamp. 
imagecopy($im, $stamp, imagesx($im) - $sx - $marge_right, imagesy($im) - $sy - $marge_bottom, 0, 0, imagesx($stamp), imagesy($stamp));

// Output and free memory
header('Content-type: image/png');
imagepng($im);
imagedestroy($im);

Example #1 Using imagecopymerge() to create a translucent watermark

<?php
// Load the stamp and the photo to apply the watermark to
$im = imagecreatefromjpeg('photo.jpeg');

// First we create our stamp image manually from GD
$stamp = imagecreatetruecolor(100, 70);
imagefilledrectangle($stamp, 0, 0, 99, 69, 0x0000FF);
imagefilledrectangle($stamp, 9, 9, 90, 60, 0xFFFFFF);
$im = imagecreatefromjpeg('photo.jpeg');
imagestring($stamp, 5, 20, 20, 'libGD', 0x0000FF);
imagestring($stamp, 3, 20, 40, '(c) 2007-9', 0x0000FF);

// Set the margins for the stamp and get the height/width of the stamp image
$marge_right = 10;
$marge_bottom = 10;
$sx = imagesx($stamp);
$sy = imagesy($stamp);

// Merge the stamp onto our photo with an opacity (transparency) of 50%
imagecopymerge($im, $stamp, imagesx($im) - $sx - $marge_right, imagesy($im) - $sy - $marge_bottom, 0, 0, imagesx($stamp), imagesy($stamp), 50);

// Save the image to file and free memory
imagepng($im, 'photo_stamp.png');
imagedestroy($im);

The only problem is that I don't know how to build a module that extends the image field.

My goal is to have an option (probably a checkbox) for every image in the image field. Checking the checkbox would watermark the image.

Can someone provide me with some hints to get started?

/Jasper

Link to comment
Share on other sites

I've had some dealings with this before, however not in ProcessWire specifically.

I agree with the idea of doing it per-image as I've had the need in the past to watermark exclusive images from computer games mized in with non-exclusive images in articles.

You will have a few potential issues with any approach - if it's a light image, you'll want to apply dark text for the watermark, and if it's a dark image you'll want to apply light text.

I would suggest an option be that you can watermark using another image (a transparent PNG) as well, but you can have the same issues as above (think I got around this by making my PNg watermark image with white text and a dark shadow so it stands out on all images).

There is actually less code involved in placing a transparent image on top of another image as well, though it would be nice to have both options configurable in such a module.

Another thing to take into account is that you only want this to be applied to large versions of images on the final page, though I guess it doesn't matter too much if the thumbnail included a tiny watermark (I'd prefer not on a thumbnail on the final page, but not sure how you would get around it as they're generated on the first page render). If you're resizing uploaded images over a certain size too (like I do) then that needs to be taken into account also as the filename has the large size appended to it, though presumably this new filename is easy enough to get hold of.

So lots to think about, but I don't know where you would start either ;)

Link to comment
Share on other sites

Another thing to take into account is that you only want this to be applied to large versions of images on the final page, though I guess it doesn't matter too much if the thumbnail included a tiny watermark (I'd prefer not on a thumbnail on the final page, but not sure how you would get around it as they're generated on the first page render).

This could probably be solved by saving the image with another name, eg image-watermark.jpg and based on the image size it the page will render them either from the source image or there watermarked image. But I don't know how to do this yet.  :P

Link to comment
Share on other sites

Pete's right that there probably are a lot of considerations here. You don't really want to add the watermark to the original because then it's going to be in other sizes (thumbnails, etc.) and you may not want that. You don't want to use a filename based on the original because then someone can pry and find your non-watermarked version. But then if you create a different filename, it's no longer tied to the original and will stick around if the original ever gets deleted–we might need to add a new hook to Pageimage::getVariations in order to solve that one. Actually I think all the issues are solvable, but just a little more work than it sounds like at first.

One approach is to put the watermark capability in it's own module:

<?php
$w = $modules->get("WatermarkImage"); 
$w->setWatermark("mark.png"); 
$image = $w->watermark($page->image, "new-file.png"); // or just $w->watermark($page->image);  

I'm guessing something like this would return the URL to the new file, or a new Pageimage object.

Another approach would be to make an autoload module that adds a new watermark() function to the Pageimage class and works the same way as the size(), width() or height() functions, returning a new Pageimage:

<?php
$image = $page->image->watermark("mark.png"); 

Still another option would be to just create a new Image fieldtype that automatically adds a watermark (configured in the field settings) to every image uploaded to it. Or, every image with the checkbox, like you mentioned. Antti's CropImage fieldtype is probably a great example to look at for how to implement a module like that. If you decide to build a new module, just let me know anything I can do to help.

  • Like 1
Link to comment
Share on other sites

  • 6 months later...

I'm not aware of any watermark modules that exist yet. Though I think that the code formmailer posted would be a good alternative for handling specific cases. I've also had good luck creating watermarks with ImageMagick, which is a unix command line util already present on most web servers. You simply exec() to it from PHP in 1 line.

Link to comment
Share on other sites

  • 4 years later...
55 minutes ago, Cengiz Deniz said:

is it possible to add watermark during uploading images ?

Page Image Manipulator allows you to watermark image variations, which is more flexible than watermarking the original on upload.

If you are concerned about sneaky visitors gaining access to the unwatermarked originals see @horst's solution here:

 

  • Like 4
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...