| Module | TaliaCore::DataTypes::IipLoader |
| In: |
lib/talia_core/data_types/iip_loader.rb
|
Loader module for IipData records. IIP records should always be created by using the create_iip method in this module as a loader. Check the DataLoader documentation to find out how to configure loaders for different MIME types.
The loader will take the original image, and create two new DataRecords which contain three different versions of the image:
Creating the pyramid images can be a time-consuming process and it may be useful to separate this from the actual import process (if, for example you want to re-import the same data set several times). The Talia distribution contains a prepare_images script that will take the original files from a given directory and create the converted files in another location, using the subdirectories thumbs, pyramids and originals respectively.
If a directory with "prepared files" exists, the prepared_images option in the environment to the path to the directory. When the loader see that environment variable, it will automatically load the prepared images from that directory.
Indicates if an original image with the given mime type should be converted to png for the "original image" record
# File lib/talia_core/data_types/iip_loader.rb, line 79
79: def convert_original?(mime_type)
80: !([:jpeg, :png].include?(mime_type.to_sym))
81: end
Pass in the empty data records (for original and iip), and fill each one by calling create_from_file with the given file
# File lib/talia_core/data_types/iip_loader.rb, line 86
86: def create_from_files(location, file, records)
87: records.each { |rec| rec.create_from_file(location, file) }
88: end
Pass in the empty data records (for original and iip), and fill them by reading the data from the io stream and calling create_from_data on each record
# File lib/talia_core/data_types/iip_loader.rb, line 93
93: def create_from_stream(location, io, records)
94: data = io.read
95: records.each { |rec| rec.create_from_data(location, data)}
96: end
Loads an image for the given file. This is a tad more complex than loading the data into a data record: It will create both an IIP data object and an Image data object. If the original is an IO stream, a temp file will be created for the conversions. See above for more.
# File lib/talia_core/data_types/iip_loader.rb, line 45
45: def create_iip(mime_type, location, source, is_file)
46: # Create the new records
47: iip_record = TaliaCore::DataTypes::IipData.new
48: image_record = TaliaCore::DataTypes::ImageData.new
49: records = [iip_record, image_record]
50: return records if(is_file && prepare_image_from_existing!(iip_record, image_record, source, location))
51:
52: if(convert_original?(mime_type))
53: # We have an image that needs to be converted
54: open_original_image(source, is_file, mime_type) do |io|
55: create_from_stream(location, io, records)
56: image_record.location = orig_location(location)
57: end
58: else
59: if(is_file)
60: create_from_files(location, source, records)
61: else
62: create_from_stream(location, source, records)
63: end
64: end
65: # IipRecord is always a (multi-leve) tiff
66: iip_record.mime = 'image/tiff'
67:
68: records
69: end
Little helper to decide how to open the original image
# File lib/talia_core/data_types/iip_loader.rb, line 133
133: def open_original_image(thing, is_file, current_type, &block)
134: if(is_file)
135: open_original_image_file(thing, &block)
136: else
137: open_original_image_stream(thing, current_type, &block)
138: end
139: end
Opens the "original" image for the given file. This will convert the image to PNG image and the yield the io object for the PNG.
# File lib/talia_core/data_types/iip_loader.rb, line 160
160: def open_original_image_file(filename)
161: converted_file = File.join(Dir.tmpdir, "talia_convert_#{rand 10E16}.png")
162: begin
163: TaliaUtil::ImageConversions.to_png(filename, converted_file)
164: File.open(converted_file) do |io|
165: yield(io)
166: end
167: ensure
168: FileUtils.rm(converted_file) if(File.exist?(converted_file))
169: end
170: end
Same as open_original_image_file, but getting the data from a stream. This writes the data to a temp file and calls open_original_file on it The temporary file is deleted after the operation
# File lib/talia_core/data_types/iip_loader.rb, line 144
144: def open_original_image_stream(io, type, &block)
145: # First load this from the web to a temp file
146: tempfile = File.join(Dir.tmpdir, "talia_down_#{rand 10E16}.#{type.to_sym}")
147: begin
148: File.open(tempfile, 'w') do |fio|
149: fio << io.read # Download the file
150: end
151: assit(File.exist?(tempfile))
152: open_original_image_file(tempfile, &block)
153: ensure
154: FileUtils.rm(tempfile) if(File.exist?(tempfile))
155: end
156: end
Rewrite the location field (filename) for "original image" data record, changing the extension to .png
# File lib/talia_core/data_types/iip_loader.rb, line 73
73: def orig_location(location)
74: File.basename(location, File.extname(location)) + '.png'
75: end
Attempts to create the records from pre-prepared images, if possible. Returns true if (and only if) the object has been created with existing data. Always false if the data_record is not an IipData object or the prepared_images option is not set.
If this method returns true, the images have been successfully prepared from pre-prepared images.
# File lib/talia_core/data_types/iip_loader.rb, line 105
105: def prepare_image_from_existing!(iip_record, image_record, url, location)
106: return false unless(iip_record.is_a?(TaliaCore::DataTypes::IipData) && image_record.is_a?(TaliaCore::DataTypes::ImageData))
107: return false unless((prep = ENV['prepared_images']) && prep.to_s.downcase != 'no' && prep.to_s.downcase != 'false')
108:
109: file_ext = File.extname(url)
110: file_base = File.basename(url, file_ext)
111:
112: # Get the file paths for each prepared image: thumb, pyramid and original
113: thumb_file = File.join( ENV['prepared_images'], 'thumbs', "#{file_base}.gif")
114: pyramid_file = File.join( ENV['prepared_images'], 'pyramids', "#{file_base}.tif")
115: # Use a pattern for the original file, since we don't know the extensions
116: orig_file_pattern = File.join(ENV['prepared_images'], 'originals', "#{file_base}.*")
117: # We need to fix the pattern
118: orig_file_pattern.gsub!(/\[/, '\\[') # Escape brackets, Dir[] doesn't like them
119: orig_file_pattern.gsub!(/\]/, '\\]')
120: orig_file_l = Dir[orig_file_pattern]
121: raise(ArgumentError, 'Original find not found for ' + url) unless(orig_file_l.size > 0)
122: orig_file = orig_file_l.first # Original is the first file matching the pattern
123: assit_block { %w(.jpg .jpeg .png).include?(File.extname(orig_file).downcase) }
124:
125: # Now create the existing records from the files
126: iip_record.create_from_existing(thumb_file, pyramid_file)
127: image_record.create_from_file(location, orig_file)
128:
129: true
130: end