Script for formatting image's EXIF output from Imagemagick

600 Views Asked by At

I need to get a string that consists of the information from the image's EXIF meta data. For example, I would like:

CameraModel, Focal Length in 35mm Format: 24mm, F11, 1/500, ISO 200

I could see all the information present from

identify -format '%[EXIF:*]' image.jpg

However, I'm having trouble consolidating the output and generate the information.

The first problem, while '%[EXIF:*]' prints all EXIF data, if I replace the star with a specific EXIF tag, it doesn't print out anything. I know I could simply print out all EXIF data a few times and use grep to get the one I need, then combine them together, but it feels better to retrieve just the value I'm looking for.

The second problem, the aperture value FNumber is in a format like "63/10", but I need it to be 6.3; Annoyingly, the shutter speed ExposureTime is like 10/5000 and I need it to be 1/500. What kind of conversion do I need for each case?

Thanks!

4

There are 4 best solutions below

2
On BEST ANSWER

This works fine for me in Imagemagick 6.9.9.29 Q16 Mac OSX.

infile="P1050001.JPG"
cameramodel=`identify -ping -format "%[EXIF:model]" "$infile"`
focallenght35=`identify -ping -format "%[EXIF:FocalLengthIn35mmFilm]" "$infile"`
fnumber1=`identify -ping -format "%[EXIF:FNumber]" "$infile" | cut -d/ -f1`
fnumber2=`identify -ping -format "%[EXIF:FNumber]" "$infile" | cut -d/ -f2`
exptime1=`identify -ping -format "%[EXIF:ExposureTime]" "$infile" | cut -d/ -f1`
exptime2=`identify -ping -format "%[EXIF:ExposureTime]" "$infile" | cut -d/ -f2`
isospeed=`identify -ping -format "%[EXIF:ISOSpeedRatings]" "$infile"`
fnumber=`echo "scale=1; $fnumber1/$fnumber2" | bc`
exptime=`echo "scale=3; $exptime1/$exptime2" | bc`
echo "CameraModel=$cameramodel, FocalLengthIn35mmFilm: $focallenght35 mm, F$fnumber, $exptime sec, ISO $isospeed"


CameraModel=DMC-FZ30, FocalLengthIn35mmFilm: 35 mm, F2.8, .125 sec, ISO 200

Or alternately,

infile="P1050001.JPG"
declare `convert -ping "$infile" -format "cameramodel=%[EXIF:model]\n focallenght35=%[EXIF:FocalLengthIn35mmFilm]\n fnumber=%[EXIF:FNumber]\n exptime=%[EXIF:ExposureTime]\n isospeed=%[EXIF:ISOSpeedRatings]\n" info:`
fnumber1=`echo $fnumber | cut -d/ -f1`
fnumber2=`echo $fnumber | cut -d/ -f2`
fnumber=`echo "scale=1; $fnumber1/$fnumber2" | bc`
exptime1=`echo $exptime | cut -d/ -f1`
exptime2=`echo $exptime | cut -d/ -f2`
exptime=`echo "scale=0; $exptime2/$exptime1" | bc`
echo "CameraModel=$cameramodel, FocalLengthIn35mmFilm: $focallenght35 mm, F$fnumber, 1/$exptime sec, ISO $isospeed"


CameraModel=DMC-FZ30, FocalLengthIn35mmFilm: 35 mm, F2.8, 1/8 sec, ISO 200

1
On

Even simpler is to use EXIFTOOL directly.

infile="P1050001.JPG"
exiftool -model -FocalLengthIn35mmFormat -FNumber -ExposureTime -ISO "$infile"

Camera Model Name               : DMC-FZ30
Focal Length In 35mm Format     : 35 mm
F Number                        : 2.8
Exposure Time                   : 1/8
ISO                             : 200

or

infile="P1050001.JPG"
exiftool -csv -model -FocalLengthIn35mmFormat -FNumber -ExposureTime -ISO "$infile"

P1050001.JPG,DMC-FZ30,35 mm,2.8,1/8,200
1
On

Here is something to get you started using awk to look for the EXIF keywords and save the corresponding setting as they go past. Then at the END it prints all it found:

#!/bin/bash

identify -format '%[EXIF:*]' a.jpg | awk -F= '
   /^exif:Model/                 {model=$2}
   /^exif:FocalLengthIn35mmFilm/ {focal=$2}
   /^exif:FNumber/               {f=$2}
   /^exif:ExposureTime/          {t=$2}
   /^exif:ISOSpeedRatings/       {ISO=$2}
   END {
      # Check if fNumber is a rational number and refactor if it is
      n=split(f,k,"/")
      if(n==2){
         f=sprintf("%.1f",k[1]/k[2]);
      }
      # Check if exposure time is a rational number and refactor if it is
      n=split(t,k,"/")
      if(n==2){
         m=int(k[2]/k[1]);
         t=sprintf("1/%d",m);
      }
      print model,focal,f,t,ISO
   }' OFS=,

Sample Output

iPhone 4,35,2.8,1/914,80

I have not tested the conversion from rational numbers too extensively... between the festive whiskies...

0
On

jzxu wrote: This is fine, too, however, I noticed the parameter -csv, how do I get rid of the comma and replace them with spaces?

One way on unix is simply to use tr to replace the command with a space as follows:

exiftool -csv -model -FocalLengthIn35mmFormat -FNumber -ExposureTime -ISO "$infile" | tr "," " "

SourceFile Model FocalLengthIn35mmFormat FNumber ExposureTime ISO
P1050001.JPG DMC-FZ30 35 mm 2.8 1/8 200


Or if you do not want the header line:

exiftool -csv -model -FocalLengthIn35mmFormat -FNumber -ExposureTime -ISO "$infile" | tail -n +2 | tr "," " "

P1050001.JPG DMC-FZ30 35 mm 2.8 1/8 200


There may be other internal EXIFTOOL formatting options. See https://sno.phy.queensu.ca/~phil/exiftool/exiftool_pod.html

I am not an expert on EXIFTOOL, so perhaps I have missed something. But I do not see a space delimited output format. However, this makes the output in tab delimited format.

infile="P1050001.JPG"
exiftool -s3 -T -model -FocalLengthIn35mmFormat -FNumber -ExposureTime -ISO "$infile"

DMC-FZ30    35 mm   2.8 1/8 200


So one could use tr to replace tabs with spaces.

exiftool -s3 -T -model -FocalLengthIn35mmFormat -FNumber -ExposureTime -ISO "$infile" | tr "\t" " "

DMC-FZ30 35 mm 2.8 1/8 200