EXIF Metadata Extraction in Clojure
Since I've been playing around with
Clojure lately, I thought I'd port the Groovy and Scala versions of the EXIF metadata extraction code to Clojure. Here's some things I ran into with Clojure:
- Have to admit, although I'm very new at the Lisp syntax, Clojure is kinda fun to work with. As with both Groovy and Scala it's nice to have a REPL to test out new ideas out. The Clojure REPL's built in help (e.g. (doc instance?) and (find-doc "instance") is a very nice touch.
- I'm not a fan of the numerous parenthesis, I suppose I'm just used to the curly brackets. I find it's hard to visualize the scope of variables. A text editor with nice bracket matching helps though (Sorry TextMate, I had to use jEdit for Clojure work)
- Writing a script still left me jonesing for an equivalent to Grape
- The clj script used in the shebang line, posted on Wikibooks, was wrong. Took me a little bit to figure out what was going on. I fixed the script on Wikibooks.
- I couldn't figure out how to neatly embed the classpath info, so I had to launch it with clj -cp /path/to/sanselan-0.97.jar readexif.clj /path/to/image.jpg
- I have absolutely no idea how to indent Clojure/Lisp code
And the code:
#! /usr/bin/env clj
(import
'(java.io File)
'(org.apache.sanselan ImageReadException Sanselan)
'(org.apache.sanselan.common IImageMetadata, RationalNumber)
'(org.apache.sanselan.formats.jpeg JpegImageMetadata)
'(org.apache.sanselan.formats.tiff TiffField TiffImageMetadata)
'(org.apache.sanselan.formats.tiff.constants ExifTagConstants GPSTagConstants TagInfo TiffConstants TiffTagConstants))
(defn print-tag-value [metadata tagInfo]
(let [field (. metadata findEXIFValue tagInfo)]
(if (nil? field)
(println (str " (" (. tagInfo name) " not found.)"))
(println (str " (" (. tagInfo name) ": " (. field getValueDescription))))))
(defn readexif [file]
(let [metadata (Sanselan/getMetadata file)]
(if (nil? metadata) (println "\tNo EXIF metdata was found"))
(if (instance? JpegImageMetadata metadata)
(do
(println " -- Standard EXIF Tags")
(print-tag-value metadata (TiffTagConstants/TIFF_TAG_XRESOLUTION))
(print-tag-value metadata (TiffTagConstants/TIFF_TAG_DATE_TIME))
(print-tag-value metadata (ExifTagConstants/EXIF_TAG_DATE_TIME_ORIGINAL))
(print-tag-value metadata (ExifTagConstants/EXIF_TAG_CREATE_DATE))
(print-tag-value metadata (ExifTagConstants/EXIF_TAG_ISO))
(print-tag-value metadata (ExifTagConstants/EXIF_TAG_SHUTTER_SPEED_VALUE))
(print-tag-value metadata (ExifTagConstants/EXIF_TAG_APERTURE_VALUE))
(print-tag-value metadata (ExifTagConstants/EXIF_TAG_BRIGHTNESS_VALUE))
(print-tag-value metadata (GPSTagConstants/GPS_TAG_GPS_LATITUDE_REF))
(print-tag-value metadata (GPSTagConstants/GPS_TAG_GPS_LATITUDE))
(print-tag-value metadata (GPSTagConstants/GPS_TAG_GPS_LONGITUDE_REF))
(print-tag-value metadata (GPSTagConstants/GPS_TAG_GPS_LONGITUDE_REF))
; simple interface to GPS data
(println " -- GPS Info")
(let [exifMetadata (. metadata getExif)]
(if (false? (nil? exifMetadata))
(do
(let [gpsInfo (. exifMetadata getGPS)]
(if (false? (nil? gpsInfo))
(let [longitude (. gpsInfo getLongitudeAsDegreesEast)
latitude (. gpsInfo getLatitudeAsDegreesNorth)]
(println (str " GPS Description: " gpsInfo))
(println (str " GPS Longitude (Degrees East):" longitude))
(println (str " GPS Latitude (Degrees North):" latitude))))))))
; Print all EXIF data
(println " -- All EXIF info")
(doseq [item (. metadata getItems)]
(println (str " " item)))
(println "")))))
;(readexif (new File (first *command-line-args*)))
(do
(let [file (new File (first *command-line-args*))]
(println (str "file: " (. file getPath)))
(readexif file)))
0 comments:
Post a Comment