Writing IPTC field data into a border

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?".
snibgo
Posts: 12159
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: Writing IPTC field data into a border

Post by snibgo »

Sorry, I don't know Macs. On Windows, I would script a loop to call the script for all the files in a directory.

Your temporary image file is JPG. Bad idea, as this is always lossy, especially as you leave the "-quality" to default. Better to use PNG (or faster to use MIFF, IM's internal format).
snibgo's IM pages: im.snibgo.com
adrianlambert

Re: Writing IPTC field data into a border

Post by adrianlambert »

snibgo wrote:I would script a loop to call the script for all the files in a directory.
Thanks I'll look into this approach.
adrianlambert wrote:JPG. Bad idea, as this is always lossy
As it's just the text at the bottom and not the input image I'm not to worried. Ultimately it will load uncompressed 16bit tiffs, then add the caption to the lower section of those files as the last step and save it as a high quality Jpeg.

You got me thinking here... I need to remove the file extension from the CURRENTIMAGE variable and reset it as jpeg specifying the quality. I believe the exported image would have the same colour profile.
adrianlambert

Re: Writing IPTC field data into a border

Post by adrianlambert »

Looking deeper into this I have used Automator on mac to get this script to add borders to a batch of images. The use of Automator isn't that important in this situation. I'm finding that when ran in a terminal or automator the script runs very slowly. I guess that there might be a way to simplify the script to allow it to work more efficiently.
Would anyone have any idea's for me to try in this regard?

Code: Select all

for f in $@

do
	export PATH=$PATH:/sw/bin:/sw/sbin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/X11R6/bin:/usr/local/bin:/usr/X11/bin:/opt/local/bin/

	# Set variables for the IPTC EXIF and ImageMagick fields

	COPYRIGHTNOTICE=`convert $f -format "%[IPTC:2:116]" info:`
	FILENAME=`convert $f -format "%t" info:`
	CAPTION=`convert $f -format "%[IPTC:2:120]" info:`
	CITY=`convert $f -format "%[IPTC:2:90]" info:`
	STATEPROVINCE=`convert $f -format "%[IPTC:2:95]" info:`
	COLOURPROFILE=`identify -verbose $f | grep -E "Grey|RGB|sRGB|CMYK" | grep -v Colorspace`
	SPECIALINSTRUCTIONS=`convert $f -format "%[IPTC:2:40]" info:`
	JOBIDENTIFIER=`convert $f -format "%[IPTC:2:103]" info:`
	IMAGEWIDTH=`convert $f -format "%w" info:`
	IMAGEHEIGHT=`convert $f -format "%h" info:`
	CAPTIONHEIGHT=$[$IMAGEHEIGHT / 20]
	CAPTIONSIZE=$IMAGEWIDTH"x"$CAPTIONHEIGHT

	echo 'Please archive original file with border. A path is embedded to remove the border | '$COPYRIGHTNOTICE' | '$FILENAME' | Caption: '$CAPTION' | '$CITY' | 	'$STATEPROVINCE' | '$COLOURPROFILE' | Usage Terms: '$SPECIALINSTRUCTIONS' | Licensee: '$JOBIDENTIFIER > ~/caption.txt

	convert -background grey -font Arial-Narrow-Bold -gravity Center -fill grey10 -size $CAPTIONSIZE caption:@caption.txt ~/caption.jpg

	
	
	convert $f -gravity North -background grey -extent 100x104% 
	composite -gravity South caption.jpg $f $f

	rm ~/caption.txt
	rm ~/caption.jpg

done
snibgo
Posts: 12159
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: Writing IPTC field data into a border

Post by snibgo »

Code: Select all

convert x.png -format %w info:-
uselessly reads and unpacks the entire image into memory before finally returning the width. Use the "-ping" option to skip the image processing.
snibgo's IM pages: im.snibgo.com
adrianlambert

Re: Writing IPTC field data into a border

Post by adrianlambert »

Code: Select all

for f in $@

do
	export PATH=$PATH:/sw/bin:/sw/sbin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/X11R6/bin:/usr/local/bin:/usr/X11/bin:/opt/local/bin/

	# Set variables for the IPTC EXIF and ImageMagick fields

	CAPTION="Please archive original file with border. A path is embedded to remove the border. | `convert -ping $f -format \"%[IPTC:2:116]\" info:` | `convert -ping $f -format "%t" info:` | Caption: `convert -ping $f -format "%[IPTC:2:120]" info:` | `convert -ping $f -format "%[IPTC:2:90]" info:` | `convert -ping $f -format "%[IPTC:2:95]" info:` |`identify -ping -verbose $f | grep -E "Grey|RGB|sRGB|CMYK" | grep -v Colorspace` | `convert -ping $f -format "%[IPTC:2:40]" info:` | Licensee: `convert -ping $f -format "%[IPTC:2:103]" info:`"
	IMAGEWIDTH=`convert -ping $f -format "%w" info:`
	IMAGEHEIGHT=`convert -ping $f -format "%h" info:`
	CAPTIONHEIGHT=$[$IMAGEHEIGHT / 20]
	CAPTIONSIZE=$IMAGEWIDTH"x"$CAPTIONHEIGHT

	echo $CAPTION > ~/caption.txt

	convert -background grey -font Arial-Narrow-Bold -gravity Center -fill grey10 -size $CAPTIONSIZE caption:@caption.txt ~/caption.jpg

	
	
	convert $f -gravity North -background grey -extent 100x104% 
	composite -quality 100 -gravity South caption.jpg $f $f

	rm ~/caption.txt
	rm ~/caption.jpg

done
Ok I've -ping(ed) all the converts. It's dropped about 25% of the time to run. I'm getting about 1 image for 30 seconds (pixel size is 3697 × 5554)
Does that sound good or not? I'm used to PS running a bit faster but aware that this might not be as efficient.
snibgo
Posts: 12159
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: Writing IPTC field data into a border

Post by snibgo »

You can probably do without either temporary file by combining the echo and final two converts. This won't help much.

You might manually "identify -verbose" to see how much text it spews out for grep to process. There may be a "set" option to reduce it. I have a vague memory of something that suppressed comments, but I can't remember or find it.

You might put timing commands in there, to find out what is taking the time. 30 seconds seems very long. I suspect most of the time is for that "CONVERT=...".

In Windows, I generally use a single convert to get all the metadata I want, rather than one convert per metadata item. I don't know how much difference this would make.
snibgo's IM pages: im.snibgo.com
adrianlambert

Re: Writing IPTC field data into a border

Post by adrianlambert »

snibgo wrote:You can probably do without either temporary file by combining the echo and final two converts. This won't help much.

You might manually "identify -verbose" to see how much text it spews out for grep to process. There may be a "set" option to reduce it. I have a vague memory of something that suppressed comments, but I can't remember or find it.

You might put timing commands in there, to find out what is taking the time. 30 seconds seems very long. I suspect most of the time is for that "CONVERT=...".

In Windows, I generally use a single convert to get all the metadata I want, rather than one convert per metadata item. I don't know how much difference this would make.
Thanks. I thought about the single convert, but it'd need some processing to separate it into the components that I want. I did do a manual identify -verbose and it wasn't that much, in fact that command with the grep was pretty fast. It probably is that and the composite. I'll keep pugging away. Thanks again
snibgo
Posts: 12159
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: Writing IPTC field data into a border

Post by snibgo »

Another possibility is to use exiftool, which might be faster than IM at extracting metadata, but I have little exprience of it.
snibgo's IM pages: im.snibgo.com
adrianlambert

Re: Writing IPTC field data into a border

Post by adrianlambert »

Thanks I'll look into that too.
good thinking.
Eric B
Posts: 14
Joined: 2010-07-05T04:27:52-07:00
Authentication code: 8675308

Re: Writing IPTC field data into a border

Post by Eric B »

As I was looking how writing the IPTC headline in the top of my image, I found this topic first.

So to retrieve the IPTC file, I also tried exiftool which is however much slower. And better than convert, Identify does the job well:

Code: Select all

identify -format "%[IPTC:2:105]" input.jpg 


As I am under Win7, I first tried normal cmd.exe, but I gave up because of a conflict interpretation of % char between cmd script in loop and the IPTC file in convert. I had also problem with empty space in filename.
More explicitely,

Code: Select all

for %%f in (%*) do call :Process %%f
pause
goto :eof
:Process 
@echo processing file %1
identify -format "%[IPTC:2:105]" %1   > test.txt
does not work.

Thus, before switching to an unix environment (cygwin), I used the opportunity to learn powershell and re wrote my script in it. After some hours of "try and error", I got good results with the following script.

Code: Select all

$outputDir="signed"

Function SignFile($file)
{
    $headline = identify -format "%[IPTC:2:105]" $file
    $curentDir = Split-Path $file
    $filesimple = Split-Path $file -leaf
    $s=$curentDir + '\' + $outputDir + '\' + $filesimple

# Define a temp image with the headline
    convert -size 600x25 xc:transparent -font Candice -pointsize 22 -gravity west -draw "fill white text 0,0 '$headline'" headline.png
    mogrify -trim +repage headline.png
#real convert
    convert $file -filter Lanczos -resize 900x900 -unsharp 0x0.6+0.75+0.02 -format JPEG -quality 95 -mattecolor white -frame 5x5 -mattecolor opaque -frame 20x20 -gravity NorthWest headline.png -compose atop -geometry +20+0 -composite $s
# del temp image
   del headline.png
}

$files=get-childitem *
foreach ($file in $files)
{    
    SignFile($file)
}
I still have to enhance the script, particularly the loop.

1) Is there a simple way to know if a file is an image? I mean a parameter of "identify" which returns true or false instead of some error? Otherwise, I filter with file extension...
2) regarding my first convert in the loop: is there a way to drive it into memory instead of filesystem?
Post Reply