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.



376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
# File 'lib/exifr/tiff.rb', line 376

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 |v|
      if v.jpeg_interchange_format && v.jpeg_interchange_format_length
        start, length = v.jpeg_interchange_format, v.jpeg_interchange_format_length
        if Integer === start && Integer === length
          data[start..(start + length)]
        else
          EXIFR.logger.warn("Non numeric JpegInterchangeFormat data")
          nil
        end
      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.



414
415
416
417
418
419
420
421
422
423
424
# File 'lib/exifr/tiff.rb', line 414

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)}.



247
248
249
# File 'lib/exifr/tiff.rb', line 247

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:



450
451
452
# File 'lib/exifr/tiff.rb', line 450

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



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

alias instance_methods_without_tiff_extras instance_methods

.rational(n, d) ⇒ Object



343
344
345
346
347
348
349
350
351
# File 'lib/exifr/tiff.rb', line 343

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



353
354
355
356
# File 'lib/exifr/tiff.rb', line 353

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

Instance Method Details

#[](index) ⇒ Object

Get index image.



409
410
411
# File 'lib/exifr/tiff.rb', line 409

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

#eachObject

Yield for each image.



404
405
406
# File 'lib/exifr/tiff.rb', line 404

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

#encode_with(coder) ⇒ Object



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

def encode_with(coder)
  coder["ifds"] = @ifds
end

#gpsObject

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



467
468
469
470
471
472
473
474
475
476
# File 'lib/exifr/tiff.rb', line 467

def gps
  return nil unless gps_latitude && gps_longitude

  altitude = gps_altitude.is_a?(Array) ? gps_altitude.first : gps_altitude

  GPS.new(gps_latitude.to_f * (gps_latitude_ref == 'S' ? -1 : 1),
          gps_longitude.to_f * (gps_longitude_ref == 'W' ? -1 : 1),
          altitude && (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.



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

def height; @ifds.first.height; end

#inspectObject

:nodoc:



478
479
480
# File 'lib/exifr/tiff.rb', line 478

def inspect # :nodoc:
  @ifds.inspect
end

#methods(regular = true) ⇒ Object

:nodoc:



432
433
434
435
436
437
438
# File 'lib/exifr/tiff.rb', line 432

def methods(regular=true) # :nodoc:
  if regular
    (super + TAGS + IFD.instance_methods(false)).uniq
  else
    super
  end
end

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

:nodoc:

Returns:

  • (Boolean)


426
427
428
429
430
# File 'lib/exifr/tiff.rb', line 426

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.



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

def size
  @ifds.size
end

#to_hashObject

Get a hash presentation of the (first) image.



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

def to_hash; @ifds.first.to_hash; end

#to_yaml_propertiesObject



444
445
446
# File 'lib/exifr/tiff.rb', line 444

def to_yaml_properties
  ['@ifds']
end

#widthObject

Convenience method to access image width.



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

def width; @ifds.first.width; end