Class: EXIFR::TIFF

Inherits:
Object
  • Object
show all
Includes:
Enumerable
Defined in:
lib/exifr/tiff.rb

Overview

TIFF decoder

Date properties

The properties :date_time, :date_time_original, :date_time_digitized coerced into Time objects.

Orientation

The property :orientation describes the subject rotated and/or mirrored in relation to the camera. It is translated to one of the following instances:

  • TopLeftOrientation

  • TopRightOrientation

  • BottomRightOrientation

  • BottomLeftOrientation

  • LeftTopOrientation

  • RightTopOrientation

  • RightBottomOrientation

  • LeftBottomOrientation

These instances of Orientation have two methods:

  • to_i; return the original integer

  • transform_rmagick(image); transforms the given RMagick::Image to a viewable version

Examples

EXIFR::TIFF.new('DSC_0218.TIF').width           # => 3008
EXIFR::TIFF.new('DSC_0218.TIF')[1].width        # => 160
EXIFR::TIFF.new('DSC_0218.TIF').model           # => "NIKON D1X"
EXIFR::TIFF.new('DSC_0218.TIF').date_time       # => Tue May 23 19:15:32 +0200 2006
EXIFR::TIFF.new('DSC_0218.TIF').exposure_time   # => Rational(1, 100)
EXIFR::TIFF.new('DSC_0218.TIF').orientation     # => EXIFR::TIFF::Orientation

Defined Under Namespace

Classes: Data, Degrees, Field, GPS, IFD, Orientation

Constant Summary collapse

TAG_MAPPING =

:nodoc:

{}
IFD_TAGS =

:nodoc:

[:image, :exif, :gps]
ORIENTATIONS =

:nodoc:

[]
ADAPTERS =

:nodoc:

Hash.new { proc { |v| v } }
TAGS =

Names for all recognized TIFF fields.

[TAG_MAPPING.keys, TAG_MAPPING.values.map{|v|v.values}].flatten.uniq - IFD_TAGS

Class Attribute Summary collapse

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(file) ⇒ TIFF

file is a filename or an IO object. Hint: use StringIO when working with slurped data like blobs.



372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
# File 'lib/exifr/tiff.rb', line 372

def initialize(file)
  Data.open(file) do |data|
    @ifds = [IFD.new(data)]
    while ifd = @ifds.last.next
      break if @ifds.find{|i| i.offset == ifd.offset}
      @ifds << ifd
    end

    @jpeg_thumbnails = @ifds.map do |ifd|
      if ifd.jpeg_interchange_format && ifd.jpeg_interchange_format_length
        start, length = ifd.jpeg_interchange_format, ifd.jpeg_interchange_format_length
        data[start..(start + length)]
      end
    end.compact
  end
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method, *args) ⇒ Object

Dispatch to first image.



405
406
407
408
409
410
411
412
413
414
415
# File 'lib/exifr/tiff.rb', line 405

def method_missing(method, *args)
  super unless args.empty?

  if @ifds.first.respond_to?(method)
    @ifds.first.send(method)
  elsif TAGS.include?(method)
    @ifds.first.to_hash[method]
  else
    super
  end
end

Class Attribute Details

.mktime_procObject

Callable to create a Time object. Defaults to proc{|*a|Time.local(*a)}.



243
244
245
# File 'lib/exifr/tiff.rb', line 243

def mktime_proc
  @mktime_proc
end

Instance Attribute Details

#jpeg_thumbnailsObject (readonly)

JPEG thumbnails



43
44
45
# File 'lib/exifr/tiff.rb', line 43

def jpeg_thumbnails
  @jpeg_thumbnails
end

Class Method Details

.instance_methods(include_super = true) ⇒ Object

:nodoc:



429
430
431
# File 'lib/exifr/tiff.rb', line 429

def instance_methods(include_super = true) # :nodoc:
  (instance_methods_without_tiff_extras(include_super) + TAGS + IFD.instance_methods(false)).uniq
end

.instance_methods_without_tiff_extrasObject



428
# File 'lib/exifr/tiff.rb', line 428

alias instance_methods_without_tiff_extras instance_methods

.rational(n, d) ⇒ Object



339
340
341
342
343
344
345
346
347
# File 'lib/exifr/tiff.rb', line 339

def self.rational(n, d)
  if d == 0
    n.to_f / d.to_f
  elsif Rational.respond_to?(:reduce)
    Rational.reduce(n, d)
  else
    n.quo(d)
  end
end

.round(f, n) ⇒ Object



349
350
351
352
# File 'lib/exifr/tiff.rb', line 349

def self.round(f, n)
  q = (10 ** n)
  (f * q).round.to_f / q
end

Instance Method Details

#[](index) ⇒ Object

Get index image.



400
401
402
# File 'lib/exifr/tiff.rb', line 400

def [](index)
  index.is_a?(Symbol) ? to_hash[index] : @ifds[index]
end

#eachObject

Yield for each image.



395
396
397
# File 'lib/exifr/tiff.rb', line 395

def each
  @ifds.each { |ifd| yield ifd }
end

#gpsObject

Get GPS location, altitude and image direction return nil when not available.



446
447
448
449
450
451
452
# File 'lib/exifr/tiff.rb', line 446

def gps
  return nil unless gps_latitude && gps_longitude
  GPS.new(gps_latitude.to_f * (gps_latitude_ref == 'S' ? -1 : 1),
          gps_longitude.to_f * (gps_longitude_ref == 'W' ? -1 : 1),
          gps_altitude && (gps_altitude.to_f * (gps_altitude_ref == "\1" ? -1 : 1)),
          gps_img_direction && gps_img_direction.to_f)
end

#heightObject

Convenience method to access image height.



438
# File 'lib/exifr/tiff.rb', line 438

def height; @ifds.first.height; end

#inspectObject

:nodoc:



454
455
456
# File 'lib/exifr/tiff.rb', line 454

def inspect # :nodoc:
  @ifds.inspect
end

#methodsObject

:nodoc:



423
424
425
# File 'lib/exifr/tiff.rb', line 423

def methods # :nodoc:
  (super + TAGS + IFD.instance_methods(false)).uniq
end

#respond_to?(method, include_all = false) ⇒ Boolean

:nodoc:

Returns:

  • (Boolean)


417
418
419
420
421
# File 'lib/exifr/tiff.rb', line 417

def respond_to?(method, include_all = false) # :nodoc:
  super ||
    (defined?(@ifds) && @ifds && @ifds.first && @ifds.first.respond_to?(method, include_all)) ||
    TAGS.include?(method)
end

#sizeObject

Number of images.



390
391
392
# File 'lib/exifr/tiff.rb', line 390

def size
  @ifds.size
end

#to_hashObject

Get a hash presentation of the (first) image.



441
# File 'lib/exifr/tiff.rb', line 441

def to_hash; @ifds.first.to_hash; end

#widthObject

Convenience method to access image width.



435
# File 'lib/exifr/tiff.rb', line 435

def width; @ifds.first.width; end