ImageMagick and EXIF Data


#1

Hi there,

I’m writing a little application that parses an image file and extracts
the
camera settings from the file (the EXIF data) and saves all the fields
to
the database. The idea is that after awhile people will be able to
search
based on camera make, model, lens settings, etc… and all the pictures
that
meet those requirements will be displayed. The picture is stored on the
file
system, and not in the DB. I’m a little lost as to where to actually
perform
the parse on the EXIF data though. I know it should probably be done in
the
image model. In my DB I have columns named “camera_model”,
“camera_make”,
“focal_length”, etc… Here’s what I ‘think’ I need to do to grab the
the
data from the image file:

def load_exif_data(image)
self.shutter_speed =
image.get_exif_by_entry(“ShutterSpeedValue”)[0][1]
self.aperture = image.get_exif_by_entry(“ApertureValue”)[0][1]
self.iso_speed = image.get_exif_by_entry(“ISOSpeedRatings”)[0][1]
self.camera_model = image.get_exif_by_entry(“Model”)[0][1]
self.focal_length = image.get_exif_by_entry(“FocalLength”)[0][1]
self.flash = image.get_exif_by_entry(“Flash”)[0][1]
self.save
end


Here’s my whole image model ( it’s a rough model, but it works for now):

require ‘RMagick’

class Image < ActiveRecord::Base

DIRECTORY = ‘public/uploaded_images’
THUMBDIRECTORY = ‘public/thumbs’
DISPLAY_DIRECTORY = ‘/public/uploaded_images/’
DISPLAYTHUMBS_DIRECTORY = ‘/public/thumbs/’

after_save :process
after_destroy :cleanup

def file_data=(file_data)
@file_data = file_data
write_attribute ‘extension’,
file_data.original_filename.split(’.’).last.downcase
write_attribute(“content_type”, file_data.content_type)
write_attribute(“original_name”, file_data.original_filename)
write_attribute(“file_size”, file_data.size)
end

def url
path.sub(/^public/,’’)
end

def to_url
return DISPLAYTHUMBS_DIRECTORY + “#{self.id}-thumb.jpg”
end

def to_large_url
return DISPLAY_DIRECTORY + “#{self.id}-full.jpg”
end

def thumbnail_url
thumbnail_path.sub(/^public/,’’)
end

def path
File.join(DIRECTORY, “#{self.id}-full.jpg”)
end

def thumbnail_path
File.join(THUMBDIRECTORY, “#{self.id}-thumb.jpg”)
end

def self.display_all_images
find(:all, :order => “created_at desc”)
end

private
#######

def process
if @file_data
create_directory
cleanup
save_fullsize
create_fullsize
create_thumbnail
load_exif_data
@file_data = nil
end
end

def save_fullsize
File.open(path,‘w’) do |file|
file.puts @file_data.read
end
end

def create_fullsize
img = Magick::Image.read(path).first
img.change_geometry!(‘700 x 700’) { |cols, rows, large|
large.resize!(cols, rows)
large.write path
}
end

def create_thumbnail
img = Magick::Image.read(path).first
img.change_geometry!(‘200 x 160’) { |cols, rows, thumbnail|
thumbnail.resize!(cols, rows)
chopped = thumbnail.chop(0, thumbnail.rows/2, thumbnail.columns/2,
thumbnail.rows)
chopped.write thumbnail_path
}
end

def create_directory
FileUtils.mkdir_p DIRECTORY
end

def cleanup
Dir[File.join(DIRECTORY, “#{self.id}-*”)].each do |filename|
File.unlink(filename) rescue nil
end
end

end

How would I actually link my load_exif_data method up to this model?

Thank you,
Dave H.