Code Monkey home page Code Monkey logo

exiftool.rb's Introduction

Ruby wrapper for ExifTool

Build Status Gem Version Code Climate

This gem is the simplest thing that could possibly work that reads the output of exiftool and renders it into a ruby hash, with correctly typed values and symbolized keys.

Ruby 2.2 through 2.4 are supported.

The latest Exiftool is recommended, but you'll get that automatically by using the exiftool_vendored gem!

Features

  • Multiget support
  • GPS latitude and longitude values are parsed as signed floats, where north and east are positive, and west and south are negative.
  • Values like shutter speed and exposure time are rendered as Rationals, which lets the caller show them as fractions (1/250) or as comparable numeric instances.
  • String values like "interop" and "serial number" are kept as strings (which preserves zero prefixes)
  • Timestamps are attempted to be interpreted with correct timezones and sub-second resolution, if the header contains that data. If the timestamp doesn't include a timezone offset, we leave it as a string, rather than inferring the current system timezone which might not be applicable to the image. We add a decimal yyyymmdd key for these problematic fields.
  • No method_missing madness
  • Excellent test coverage
  • Clean, readable code
  • MIT license

Usage

require 'exiftool'
e = Exiftool.new("path/to/iPhone 4S.jpg")
e.to_hash
# => {:make => "Apple", :gps_longitude => -122.47566667, …
e.to_display_hash
# => {"Make" => "Apple", "GPS Longitude" => -122.47566667, …

Multiget support

This gem supports Exiftool's multiget, which lets you fetch metadata for many files at once.

This can be dramatically more efficient than spinning up the exiftool process for each file due to the cost of spinning up perl.

Supply an array to the Exiftool initializer, then use .result_for:

require 'exiftool'
e = Exiftool.new(Dir["**/*.jpg"])
result = e.result_for("path/to/iPhone 4S.jpg")
result.to_hash
# => {:make => "Apple", :gps_longitude => -122.47566667, …
result[:gps_longitude]
# => -122.47566667

Or iterate through files_with_results:

e.files_with_results
# => ["path/to/iPhone 4S.jpg", "path/to/Droid X.jpg", …

Dates without timezones

It seems that most exif dates don't include timezone offsets, without which forces us to assume the current timezone is applicable to the image, which isn't necessarily correct.

To be correct, we punt and return the exiftool-formatted string, which will be something like %Y:%m:%d %H:%M:%S.

If the clock was set correctly on your camera, the date will be the correct calendar day as far as you were concerned when you took the photo. Given that, we add a _civil key associated to just the calendar date of the field, which should be safe-ish.

require 'exiftool'
e = Exiftool.new("test/IMG_2452.jpg")
e[:date_time_original]
=> "2011:07:06 09:46:45"
e[:date_time_original_civil]
=> #<Date: 2011-07-06 ((2455749j,0s,0n),+0s,2299161j)>

When things go wrong

  • Exiftool::NoSuchFile is raised if the provided filename doesn't exist.
  • Exiftool::ExiftoolNotInstalled is raised if exiftool isn't in your PATH.
  • If ExifTool has a problem reading EXIF data, no exception is raised, but #errors? will return true:
Exiftool.new("Gemfile").errors?
#=> true

Installation

Step 1: Install ExifTool

The easiest way is to use the "vendored" exiftool in the exiftool_vendored gem. Just add

gem 'exiftool_vendored'

to your Gemfile, run bundle, and you're done. (Note that it depends on the exiftool gem, so really, you're done! Skip step 2!)

If you want to install exiftool on your system yourself:

  • MacOS with homebrew? brew install exiftool
  • Debian or Ubuntu? sudo apt-get install libimage-exiftool-perl
  • Something else? RTFM!

Step 2: Add the gem

If you didn't use exiftool_vendored, then add this your Gemfile:

gem 'exiftool'

and then run bundle.

If you have exiftool installed outside of ruby's PATH, add an initializer that points the gem to the tool, like this: Exiftool.command = '/home/ruby/Image-ExifTool-9.33/exiftool'. You don't need to do this if you've installed added the exiftool directory to the PATH of the shell that runs ruby.

Change history

1.2.1

  • Fixed exiftool_installed?, referenced by issue #11.

1.2.0

1.1.0

  • Support Pathname instances as constructor args. Addresses issue #8

  • Dropped official support for jruby due to CI failures.

1.0.1

0.8.0

  • Updates from Sergey Morozov to support newer rubies, and validate UTF field parsing was handled correctly

0.7.0

  • Added zero-date parsing to address issue #2. Thanks for the pull request, Sergey Morozov!
  • Updated Travis configuration (RIP 1.9.x).

0.5.0

  • Introduced YMD parsing for all date columns, even if they don't specify timezone offsets.

0.4.0

  • Added #raw_hash to Exiftool::Result to support columns that can have parsing issues, like dates that don't include timezone offsets.

0.3.1

  • .exiftool_version is now a string rather than a float, which didn't work so well with version numbers like "9.40"

0.3.0

  • Support for explicitly setting the path to exiftool with Exiftool.command
  • Removed the test directory from the gem contents, as it included the test images and made the gem ginormous.

0.2.0

  • Renamed from exiftoolr to exiftool

0.1.0

  • Better timestamp parsing—now both sub-second and timezone offsets are handled correctly
  • Switched to minitest-spec
  • Ruby 1.8.7 is no longer supported, hence the minor version uptick.

0.0.9

  • Explicitly added MIT licensing to the gemspec.

0.0.8

  • Extracted methods in parsing to make the code complexity lower. FOUR DOT OH GPA

0.0.7

  • Added warning values for EXIF headers that are corrupt
  • Made initialize gracefully accept an empty array, or an array of Pathname instances
  • Added support for ruby 1.9.3 and exiftool v8.15 (Ubuntu Natty) and v8.85 (current stable version)

0.0.5

Fixed homepage URL in gemspec

0.0.4

Added support for multiple file fetching (which is much faster for large directories)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.