Estatistics
Estatistics

Reputation: 946

Using Imagemagick, save its variables per use

History: I try to apply a watermark on a series of images in a directory, at linux, putting that watemark on an extra created space / border below the image. Both Watermark and the extra space is resized / created depending on the height size on the image they are applied.

I do various calculations based on the height of the image that is processed each time that they are saved on some variables. However, I do not know how to a) Make a script to be applied to all the images on the directory, using the saved height calculations PER IMAGE, OR b) to be applied these calculations PER IMAGE, as "single terminal command" e.g. "for pic in DSC*.*; do height calculations....... and saved at that variable to be used for the next batch terminal command"

The variables of imagemagick. How I saved them to be used for the next use, per image?

height=`convert DSC__12.jpg -format "%w" info:`
yoff_p50=`convert xc: -format "%[fx:$height/50]" info:`
yoff_p100=`convert xc: -format "%[fx:$height/100]" info:`
yoff_p200=`convert xc: -format "%[fx:$height/200]" info:`

I tried the following linux terminal command: Is there a better elegant (shorter?) way?

for pic in DSC*.*;  
do  height=`convert "$pic" -format "%w" info:`; 
yoff_p50=`convert xc: -format "%[fx:$height/50]" info:`; 
yoff_p100=`convert xc: -format "%[fx:$height/100]" info:`; 
yoff_p200=`convert xc: -format "%[fx:$height/200]" info:`; 
convert -background black -gravity NorthWest -extent 0%x0%+0+${yoff_p50} -pointsize ${yoff_p100} -fill white -undercolor '#00000080' -gravity SouthWest  -annotate  +${yoff_p100}+${yoff_p200} "$(stat -c '%y' "$pic")" "$pic" "${pic//.*}-d.jpg"; 
done;


for pic in DSC*-d.*; 
do  height=`convert "$pic" -format "%w" info:`; 
yoff_p50=`convert xc: -format "%[fx:$height/50]" info:`; 
yoff_p100=`convert xc: -format "%[fx:$height/100]" info:`; 
yoff_p200=`convert xc: -format "%[fx:$height/200]" info:`; 
 convert /home/elias/Data/PHOTOS/watermark_0.png    -resize ${yoff_p50}x${yoff_p50}^     /home/elias/Data/PHOTOS/res_watermark_0.png;
composite -dissolve 100% -gravity SouthEast /home/elias/Data/PHOTOS/res_watermark_0.png "$pic" "${pic//.*}-marked.jpg"; 
done; 

ps. How I can check what values are saved per imagemagick variable?

UPDATE: Solution: The solution by Mark Setchell worked.

Finally, i run: ..and it did the job from linux terminal very fine.

    for pic in DSC*.* ; do
       #Save either the date of File Creation or Modification on filename
       exiftool "-FileName<CreateDate" -d  "${pic//.*}_%Y%m%d_%H%M%S.jpg" "$pic"   &&   exiftool "-FileName<FileModifyDate" -d  "${pic//.*}_%Y%m%d_%H%M%S.jpg" "$pic" ; 
done;
    
for pic in DSC*.* ; do
   # Determine offsets and sizes
   read w y1 y2 y3 < <(identify -format "%w %[fx:w/50] %[fx:w/100] %[fx:w/200]" "$pic");
   ts=$(stat -c '%y' "$pic");

   convert -size ${w}x${y1} xc:black -gravity SouthWest \
      -pointsize ${y2} -fill white -undercolor '#00000080' -annotate +${y2}+${y3} "$ts"  \
      \( /home/elias/Data/PHOTOS/res_watermark_0.png -resize "${y1}x${y1}^" \) -gravity East -composite \
      "$pic" +swap -append "${pic//.*}-marked.jpg";
done

Upvotes: 2

Views: 806

Answers (2)

fmw42
fmw42

Reputation: 53164

Another way to save variables in one ImageMagick command is using declare.

declare `convert xc: -format "yoff_p50=%[fx:$height/50]\nyoff_p100=%[fx:$height/50]\nyoff_p200=%[fx:$height/200]\n" info:`

Example:

declare `convert rose: -format "ww=%[fx:w]\nhh=%[fx:h]\n" info:` echo "ww=$ww; hh=$hh;"

ww=70; hh=46;

Upvotes: 1

Mark Setchell
Mark Setchell

Reputation: 207758

It can probably be improved further, but I would go with something more like this:

#!/bin/bash

for f in DSC* ; do
   # Determine offsets and sizes
   read w y1 y2 y3 < <(identify -format "%w %[fx:w/50] %[fx:w/100] %[fx:w/200]" "$f")

   # Get timestamp - different on macOS. You want: ts=$(stat -c '%y' "$f")
   ts=$(stat -f "%Sm%n" "$f")

   convert -size ${w}x${y1} xc:black -gravity SouthWest \
      -pointsize ${y2} -fill white -undercolor '#00000080' -annotate +${y2}+${y3} "$ts"  \
      \( watermark.png -resize "${y1}x${y1}^" \) -gravity East -composite \
      "$f" +swap -append watermarked-"$f".jpg
done

Things to note:

  • The line beginning read w y1... gets all the calculated values in a single go - this will be quicker.

  • The line beginning ts=$(...) gets the timestamp. I abstracted it out because I am on macOS and it is different. You can re-integrate it, if you want.

The final line is where the action is. I create a black annotation bar the right size first, then write in the timestamp in white on the left. Then, on the next line I load the watermark and resize it and splat it into the right corner of the black annotation bar. Then, on the next line, I load the main image, and swap the order so the annotation bar is at the bottom and the image is at the top before appending.

Remember when debugging ImageMagick scripts, you can add in -write "debug.png" at any position to see how something looks after resizing , or before compositing or wherever.

Upvotes: 1

Related Questions