133 lines
4.6 KiB
Ruby
133 lines
4.6 KiB
Ruby
###############################################################################
|
|
# TASK: generate_derivatives
|
|
#
|
|
# create small and thumb images for image and pdf files in the 'objects' folder
|
|
###############################################################################
|
|
|
|
require 'image_optim' unless Gem.win_platform?
|
|
require 'mini_magick'
|
|
|
|
def process_and_optimize_image(filename, file_type, output_filename, size, density)
|
|
image_optim = ImageOptim.new(svgo: false) unless Gem.win_platform?
|
|
if filename == output_filename && file_type == :image && !Gem.win_platform?
|
|
puts "Optimizing: #{filename}"
|
|
begin
|
|
image_optim.optimize_image!(output_filename)
|
|
rescue StandardError => e
|
|
puts "Error optimizing #{filename}: #{e.message}"
|
|
end
|
|
elsif filename == output_filename && file_type == :pdf
|
|
puts "Skipping: #{filename}"
|
|
else
|
|
puts "Creating: #{output_filename}"
|
|
begin
|
|
if file_type == :pdf
|
|
inputfile = "#{filename}[0]"
|
|
magick = MiniMagick.convert
|
|
magick.density(density)
|
|
magick << inputfile
|
|
magick.resize(size)
|
|
magick.flatten
|
|
magick << output_filename
|
|
magick.call
|
|
else
|
|
magick = MiniMagick.convert
|
|
magick << filename
|
|
magick.resize(size)
|
|
magick.flatten
|
|
magick << output_filename
|
|
magick.call
|
|
end
|
|
image_optim.optimize_image!(output_filename) unless Gem.win_platform?
|
|
rescue StandardError => e
|
|
puts "Error creating #{filename}: #{e.message}"
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
desc 'Generate derivative image files from collection objects'
|
|
task :generate_derivatives, [:thumbs_size, :small_size, :density, :missing, :compress_originals, :input_dir] do |_t, args|
|
|
# set default arguments
|
|
# default image size is based on max pixel width they will appear in the base template features
|
|
args.with_defaults(
|
|
thumbs_size: '450x',
|
|
small_size: '800x800',
|
|
density: '300',
|
|
missing: 'true',
|
|
compress_originals: 'false',
|
|
input_dir: 'objects'
|
|
)
|
|
|
|
# set the folder locations
|
|
objects_dir = args.input_dir
|
|
thumb_image_dir = objects_dir + '/thumbs'
|
|
small_image_dir = objects_dir + '/small'
|
|
|
|
# Ensure that the output directories exist.
|
|
[objects_dir, thumb_image_dir, small_image_dir].each do |dir|
|
|
FileUtils.mkdir_p(dir) unless Dir.exist?(dir)
|
|
end
|
|
|
|
# support these file types
|
|
EXTNAME_TYPE_MAP = {
|
|
'.jpeg' => :image,
|
|
'.jpg' => :image,
|
|
'.pdf' => :pdf,
|
|
'.png' => :image,
|
|
'.tif' => :image,
|
|
'.tiff' => :image
|
|
}.freeze
|
|
|
|
# CSV output
|
|
list_name = File.join(objects_dir, 'object_list.csv')
|
|
field_names = 'filename,object_location,image_small,image_thumb'.split(',')
|
|
CSV.open(list_name, 'w') do |csv|
|
|
csv << field_names
|
|
|
|
# Iterate over all files in the objects directory.
|
|
Dir.glob(File.join(objects_dir, '*')).each do |filename|
|
|
# Skip subdirectories and the README.md file.
|
|
if File.directory?(filename) || File.basename(filename) == 'README.md' || File.basename(filename) == 'object_list.csv'
|
|
next
|
|
end
|
|
|
|
# Determine the file type and skip if unsupported.
|
|
extname = File.extname(filename).downcase
|
|
file_type = EXTNAME_TYPE_MAP[extname]
|
|
unless file_type
|
|
puts "Skipping file with unsupported extension: #{filename}"
|
|
csv << ["#{File.basename(filename)}", "/#{filename}", nil, nil]
|
|
next
|
|
end
|
|
|
|
# Get the lowercase filename without any leading path and extension.
|
|
base_filename = File.basename(filename, '.*').downcase
|
|
|
|
# Optimize the original image.
|
|
if args.compress_originals == 'true'
|
|
puts "Optimizing: #{filename}"
|
|
process_and_optimize_image(filename, file_type, filename, nil, nil)
|
|
end
|
|
|
|
# Generate the thumb image.
|
|
thumb_filename = File.join(thumb_image_dir, "#{base_filename}_th.jpg")
|
|
if args.missing == 'false' || !File.exist?(thumb_filename)
|
|
process_and_optimize_image(filename, file_type, thumb_filename, args.thumbs_size, args.density)
|
|
else
|
|
puts "Skipping: #{thumb_filename} already exists"
|
|
end
|
|
|
|
# Generate the small image.
|
|
small_filename = File.join([small_image_dir, "#{base_filename}_sm.jpg"])
|
|
if (args.missing == 'false') || !File.exist?(small_filename)
|
|
process_and_optimize_image(filename, file_type, small_filename, args.small_size, args.density)
|
|
else
|
|
puts "Skipping: #{small_filename} already exists"
|
|
end
|
|
csv << ["#{File.basename(filename)}", "/#{filename}", "/#{small_filename}", "/#{thumb_filename}"]
|
|
end
|
|
end
|
|
puts "\e[32mSee '#{list_name}' for list of objects and derivatives created.\e[0m"
|
|
end
|