A Ruby EXIF reader written in C.
$ gem install exif
Please make sure you have installed libexif
:
$ brew install libexif # Homebrew
$ sudo apt-get install libexif-dev # APT
$ sudo yum install libexif-devel # CentOS
data = Exif::Data.new(IO.read('sample.jpg')) # load from string
data = Exif::Data.new("Exif\x00\x00II...") # load raw exif data
data = Exif::Data.new(File.open('sample.jpg')) # load from file
data.model # => "NIKON D600"
data.image_width # => 4000
data.gps_longitude # => [(121/1), (76869/2500), (0/1)]
data.date_time # => "2013:12:08 21:14:11"
# get all entries in an IFD
data[:ifd0] # => {image_width: 4000, image_length: 2670, ...}
data[:ifd1] # => {x_resolution: (72/1), y_resolution: (72/1), ...}
data[:exif] # => exposure_time: (1/125), fnumber: (8/1)}
data[:gps] # => {gps_version_id: [2, 2, 0, 0], gps_latitude_ref: "N", ...}
data[:interoperability] # => {...}
data.to_h # => {:ifd0 => {...}, :ifd1 => {...}, :exif => {...}}
data.ifds == data.to_h # => true
ifd0
takes precedence over ifd1
, since ifd0
and ifd1
share the same domain of tags, sometimes the same tag can be both used inside them, in this case, calling top-level API like Exif::Data#image_width
will return the value of ifd0
.
Tag Type | Ruby Class |
---|---|
ASCII | String |
BYTE | Integer |
DOUBLE | Flat |
FLOAT | Float |
LONG | Integer |
RATIONAL | Rational |
SHORT | Integer |
UNDEFINED | String |
It's hundreds of times faster than mini_exiftool or exiftool and several times faster than exifr.
There are similar excellent gems like exifr, mini_exiftool and exiftool built in pure Ruby while this one is a C extension.
If you are using JRuby you might want to give exifr, exiftool or mini_exiftool a look, the latter two are commandline wrappers for ExifTool by Phil Harvey and support many file formats. The exiftool gem can process multiple files at once while mini_exiftool can modify or copy EXIF data.
You can find all benchmark files in /benchmark:
Read a single tag from 100 files.
$ ruby benchmark/load_file.rb
Rehearsal ---------------------------------------------------------
mini_exiftool (2.9.0) 0.240000 0.110000 22.830000 ( 23.275885)
exiftool (1.2.0) 0.480000 0.130000 22.870000 ( 23.311755)
exifr (1.3.2) 0.120000 0.010000 0.130000 ( 0.139821)
exif (49b6835) 0.020000 0.000000 0.020000 ( 0.019927)
----------------------------------------------- total: 45.850000sec
user system total real
mini_exiftool (2.9.0) 0.240000 0.120000 22.830000 ( 23.267355)
exiftool (1.2.0) 0.490000 0.130000 23.190000 ( 23.678799)
exifr (1.3.2) 0.120000 0.010000 0.130000 ( 0.134572)
exif (49b6835) 0.020000 0.000000 0.020000 ( 0.018419)
-----------------------------------------
1263 times faster than mini_exiftool (2.9.0)
1286 times faster than exiftool (1.2.0)
7 times faster than exifr (1.3.2)
Read many tags from the same file 1000 times.
$ ruby benchmark/read_tag.rb
Rehearsal ---------------------------------------------------------
mini_exiftool (2.9.0) 0.390000 0.000000 0.390000 ( 0.404067)
exiftool (1.2.0) 0.030000 0.000000 0.030000 ( 0.027073)
exifr (1.3.2) 1.220000 0.020000 1.240000 ( 1.268672)
exif (49b6835) 0.010000 0.000000 0.010000 ( 0.006862)
------------------------------------------------ total: 1.670000sec
user system total real
mini_exiftool (2.9.0) 0.410000 0.010000 0.420000 ( 0.412627)
exiftool (1.2.0) 0.030000 0.000000 0.030000 ( 0.028518)
exifr (1.3.2) 1.180000 0.010000 1.190000 ( 1.203806)
exif (49b6835) 0.010000 0.000000 0.010000 ( 0.006925)
-----------------------------------------
60 times faster than mini_exiftool (2.9.0)
4 times faster than exiftool (1.2.0)
174 times faster than exifr (1.3.2)