Watermark an entire directory

Questions and postings pertaining to the usage of ImageMagick regardless of the interface. This includes the command-line utilities, as well as the C and C++ APIs. Usage questions are like "How do I use ImageMagick to create drop shadows?".
Post Reply
strantheman

Watermark an entire directory

Post by strantheman »

Hi all, and thank you Bonzo and Anthony for all your help last time :)

I am doing some more stuff for a different client, and this time I am trying to apply a watermark to every JPG in a directory, overwriting the original.

This command does work for a single image:

Code: Select all

composite -compose atop -gravity southeast -geometry +10+10 ../wm.png 1.jpg 1.jpg
This is the command I tried for the entire directory:

Code: Select all

composite -compose atop -gravity southeast -geometry +10+10 ../wm.png "*.jpg" "*.jpg"
I read that using quotes around wild cards can be helpful, so thats why those are there.

thanks in advance guys!

nic
Bonzo
Posts: 2971
Joined: 2006-05-20T08:08:19-07:00
Location: Cambridge, England

Re: Watermark an entire directory

Post by Bonzo »

I am glad you got sorted OK nic.

I think you need to do something like this:

Code: Select all

mogrify  -draw \"image Over 100,100 225,225 watermark.gif\" *.jpg
Acording to the ImageMagick site -composite should work but it does not for me using 6.3.4
strantheman

Re: Watermark an entire directory

Post by strantheman »

Hi Bonzo

Well I tried that command but this is the response I got:

Code: Select all

mogrify: Non-conforming drawing primitive definition 'image'
The "composite" command works perfect for one image, and I have been using it to process images that I have in a database one image at a time no problem, but trying to just batch an entire directory with one command appears to be a little more difficult than I thought. I was sure there was an easy way to do this.

You said "composite" wasn't working for you? At all or just for batching?

thanks again

nic
Bonzo
Posts: 2971
Joined: 2006-05-20T08:08:19-07:00
Location: Cambridge, England

Re: Watermark an entire directory

Post by Bonzo »

It worked Ok for me nic I am using 6.5.4 and 6.5.5. You could try changing the \" to ' and see if that has any effect.

According to the way I read the ImageMagick website something like this should work but dosen't for me.

Code: Select all

mogrify watermark.gif *.jpg -gravity south -composite
I get the error mogrify: unrecognized option `-composite'
strantheman

Re: Watermark an entire directory

Post by strantheman »

Hey bud, nope unfortunately that did not work for me either. When I tried different quotes I got the same error but with a period instead of "image"

Code: Select all

mogrify: Non-conforming drawing primitive definition `.'.
I hope maybe the moderator Anthony will stumble over this post and give it a shot. If I can't find something this week I guess I'll just have to use PHP and loop over all of the files in the directory myself and perform the command on each file individually.
Bonzo
Posts: 2971
Joined: 2006-05-20T08:08:19-07:00
Location: Cambridge, England

Re: Watermark an entire directory

Post by Bonzo »

That is strange nic; I suppose the server setup can have an effect.

I did loop through the directory the first time I tried it ( second bit of code ): http://www.rubblewebs.co.uk/imagemagick/code.php

You could use glob instead as that would be a shorter code.

Code: Select all

foreach (glob($dir."{*.jpg,*.png,*.gif}",GLOB_BRACE ) as $filename) {
exec("composite -compose atop -gravity southeast -geometry +10+10 ../wm.png $filename $filename
}
Or something similar :)
strantheman

Re: Watermark an entire directory

Post by strantheman »

Nifty! I've been working with PHP for over a year and that's the first i've heard of GLOB. Looked it up and that looks nice. I'd been doing it all the hard way :)

That still ended up being a big help, heh thanks.

nic
Bonzo
Posts: 2971
Joined: 2006-05-20T08:08:19-07:00
Location: Cambridge, England

Re: Watermark an entire directory

Post by Bonzo »

I only found out about Glob this year as well and it does simplfy things.
User avatar
anthony
Posts: 8883
Joined: 2004-05-31T19:27:03-07:00
Authentication code: 8675308
Location: Brisbane, Australia

Re: Watermark an entire directory

Post by anthony »

strantheman wrote:Hey bud, nope unfortunately that did not work for me either. When I tried different quotes I got the same error but with a period instead of "image"

Code: Select all

mogrify: Non-conforming drawing primitive definition `.'.
I hope maybe the moderator Anthony will stumble over this post and give it a shot. If I can't find something this week I guess I'll just have to use PHP and loop over all of the files in the directory myself and perform the command on each file individually.
Well I eventually stumbled over it...
Non-conforming drawing primitive definition
That means the -draw did not see all the arguments and setting it needed for that drawing primative. In your case it was probably that you escaped your quotes, making the parts of the draw string individual options, and NOT as SINGLE STRING.


Draw only takes ONE STRING, for all the draw commands and arguments.

Remove those backslashes..


Mogrify can NOT use -composite as it only deals with one image at a time. The -draw in mogrify adds the needed extra image as an argument, outside the normal image processing sequence.

composite only wants two or three images only. anything else is ignored. With three images the thrid would have been a mask any you would have gotten unexpected results being saved in the LAST image filename you gave, overwriting that image.


As for GLOB... That is the Command line shell method for handling and expanding the special 'shell filename meta-characters, like *, ?, and {}. It lets you do the expansion into a list of files in PHP and then loop on them, rather than having either the shell, (or if you quoted the globbed filename) ImageMagick doing the filename expansion.

WARNING: As a security issue, you should watch out for filenames that contain 'glob' meta-characters too as both IM and Shells will try to re-expand them again.
The problem is a file called 'I *?@;${&) a lot.jpg' is a perfectly legal filename under UNIX, but a LOT of programs will have trouble handling it if those programs (like shell and IM) also do filename globbing.

As a security measure it is often a good idea to error and abort if a filename has some unknown or unusual characters in it (like white space or glob meta-chars). Before passing such problem files to a shell command, or IM.

I started a 'security section' to the IM Examples API info area, which will appear in a day to two.
http://www.imagemagick.org/Usage/api/#security

Bonzo, you especially better read and understand it, or copy and expand on it.
Anthony Thyssen -- Webmaster for ImageMagick Example Pages
https://imagemagick.org/Usage/
strantheman

Re: Watermark an entire directory

Post by strantheman »

Hey Anthony thanks for the reply.

Well you and Bonzo were both correct, it was just the quotes that was my problem. But check this out, this did not work:

Code: Select all

mogrify -draw "image Over 100,100 619,102 ../../tcs_wm_big.png" *.jpg
But when I put the PNG reference in single quotes, it did:

Code: Select all

mogrify -draw "image Over 100,100 619,102 '../../tcs_wm_big.png'" *.jpg
So it was a very simple problem I just didnt guess I'd need quotes if there were no spaces. So, here is the end result. I wanted to use -geometry and -gravity so that the watermark was +10+10 from the lower right corner, not just at specific coords. Here is my final command:

Code: Select all

mogrify -gravity southeast -geometry +10+10 -draw "image Over 0,0 619,102 '../../tcs_wm_big.png'" *.jpg
This did exactly what I needed! My project ended up being slightly more complex, however. I had to make a BIG and a SMALL watermark for use with different size images. The client had some 600 wide, and some 2048 wide JPGs, so I ended up having to write a PHP script anyway. I don't know if there was an easier way to identify the image width/height, but I just used an exec() and output the results from an IDENTIFY command.

For posterity's sake, and in case anyone can be helped by this, im including my entire PHP script. All that one would have to do is change the locations / if else logic for the different size watermarks, and the paths of course. There are 2 echo commands, as I like to run batch scripts like this from the command line using "php -q myscript.php" and I can then see some status output for each file.

Code: Select all

<?php
// open source, written by Stransky Design, Sept. 23, 2007
// loops over all images in a directory
// checks their dimensions
// those that are <=1024 will get the small watermark
// those that are >1024 will get the big watermark
// originals are overwritten

$dir = '../../images/gallery/';

foreach (glob($dir."{*.jpg,*.jpeg,*.pjpeg,*.png,*.gif}",GLOB_BRACE ) as $filename) {
	echo "\n$filename ...";

	$output = 'none';
	$output = exec(
		"identify " . $filename . "\n
		"
	);

	$width=0;
	$height=0;
	$orientation='none';

	list($image, $format, $geometry) = split('[ ]',$output);
	list($width, $height) = split('[x]',$geometry);

	if($width<=1024) {
		$wm = 'tcs_wm_sm.png';
	} else {
		$wm = 'tcs_wm_big.png';
	}
	exec(
		"composite -compose atop -gravity southeast -geometry +10+10 ../../images/" . $wm . " " . $filename . " " . $filename . "\n
		"
		);
	echo " ... done!\n";
}

?>
Post Reply