Skip to content

Commit

Permalink
Merge pull request sul-dlss#109 from curationexperts/use_iiif_gem
Browse files Browse the repository at this point in the history
Use the iiif-image-api gem for the models
  • Loading branch information
aaron-collier authored Oct 5, 2017
2 parents 753ed1d + 341ff7b commit 6acf20d
Show file tree
Hide file tree
Showing 34 changed files with 270 additions and 802 deletions.
4 changes: 2 additions & 2 deletions app/controllers/riiif/images_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ module Riiif
class ImagesController < ::ApplicationController
before_action :link_header, only: [:show, :info]

rescue_from Riiif::InvalidAttributeError do
rescue_from IIIF::Image::InvalidAttributeError do
head 400
end

Expand Down Expand Up @@ -120,7 +120,7 @@ def server_info
CONTEXT => CONTEXT_URI,
ID => request.original_url.sub('/info.json', ''),
PROTOCOL => PROTOCOL_URI,
PROFILE => [LEVEL1, 'formats' => OptionDecoder::OUTPUT_FORMATS]
PROFILE => [LEVEL1, 'formats' => IIIF::Image::OptionDecoder::OUTPUT_FORMATS]
}
end
end
Expand Down
20 changes: 2 additions & 18 deletions app/models/riiif/image.rb
Original file line number Diff line number Diff line change
@@ -1,21 +1,5 @@
require 'digest/md5'

##
# These explict requires are needed because in some contexts the Rails
# autoloader can either: unload already loaded classes, or cause a lock while
# trying to load a needed class.
require_dependency 'riiif/region/absolute'
require_dependency 'riiif/region/full'
require_dependency 'riiif/region/percentage'
require_dependency 'riiif/region/square'

require_dependency 'riiif/size/absolute'
require_dependency 'riiif/size/best_fit'
require_dependency 'riiif/size/full'
require_dependency 'riiif/size/height'
require_dependency 'riiif/size/percent'
require_dependency 'riiif/size/width'

module Riiif
class Image
extend Deprecation
Expand Down Expand Up @@ -60,14 +44,14 @@ def render(args)
key = Image.cache_key(id, cache_opts)

cache.fetch(key, compress: true, expires_in: Image.expires_in) do
file.extract(OptionDecoder.decode(args, info), info)
file.extract(IIIF::Image::OptionDecoder.decode(args), info)
end
end

def info
@info ||= begin
result = info_service.call(id, file)
ImageInformation.new(result[:width], result[:height])
ImageInformation.new(width: result[:width], height: result[:height])
end
end

Expand Down
31 changes: 8 additions & 23 deletions app/models/riiif/image_information.rb
Original file line number Diff line number Diff line change
@@ -1,41 +1,26 @@
module Riiif
# This is the result of calling the Riiif.image_info service. It stores the height & width
class ImageInformation
class ImageInformation < IIIF::Image::Dimension
extend Deprecation

def initialize(width, height)
@width = width
@height = height
def initialize(*args)
if args.size == 2
Deprecation.warn(self, 'calling initialize without kwargs is deprecated. Use height: and width:')
super(width: args.first, height: args.second)
else
super
end
end

attr_reader :width, :height

def to_h
{ width: width, height: height }
end

def aspect_ratio
width.to_f / height
end

def [](key)
to_h[key]
end
deprecation_deprecate :[] => 'Riiif::ImageInformation#[] has been deprecated ' \
'and will be removed in version 2.0. Use Riiif::ImageInformation#to_h and ' \
'call #[] on that result OR consider using #height and #width directly.'

# Image information is only valid if height and width are present.
# If an image info service doesn't have the value yet (not characterized perhaps?)
# then we wouldn't want to cache this value.
def valid?
width.present? && height.present?
end

def ==(other)
other.class == self.class &&
other.width == width &&
other.height == height
end
end
end
35 changes: 0 additions & 35 deletions app/models/riiif/transformation.rb

This file was deleted.

129 changes: 99 additions & 30 deletions app/services/riiif/crop.rb
Original file line number Diff line number Diff line change
@@ -1,54 +1,123 @@
module Riiif
# Represents a cropping operation
class Crop
attr_reader :image_info
# @param transformation [IIIF::Image::Region] the result the user requested
# @param image_info []
def initialize(region, image_info)
@region = region
@image_info = image_info
end

attr_reader :image_info, :region

# @return [String] a region for imagemagick to decode
# (appropriate for passing to the -crop parameter)
def to_imagemagick
"#{width}x#{height}+#{offset_x}+#{offset_y}"
case region
when IIIF::Image::Region::Full
nil
when IIIF::Image::Region::Absolute
"#{region.width}x#{region.height}+#{region.offset_x}+#{region.offset_y}"
when IIIF::Image::Region::Square
imagemagick_square
when IIIF::Image::Region::Percent
imagemagick_percent
else
raise "Unknown region #{region.class}"
end
end

# @return [String] a region for kakadu to decode
# (appropriate for passing to the -region parameter)
def to_kakadu
"\{#{decimal_offset_y},#{decimal_offset_x}\},\{#{decimal_height},#{decimal_width}\}"
case region
when IIIF::Image::Region::Full
nil
when IIIF::Image::Region::Absolute
"\{#{decimal_offset_y(region.offset_y)},#{decimal_offset_x(region.offset_x)}\}," \
"\{#{decimal_height(region.height)},#{decimal_width(region.width)}\}"
when IIIF::Image::Region::Square
kakadu_square
when IIIF::Image::Region::Percent
kakadu_percent
else
raise "Unknown region #{region.class}"
end
end

attr_reader :offset_x
private

attr_reader :offset_y
def imagemagick_percent
offset_x = (image_info.width * percentage_to_fraction(region.x_pct)).round
offset_y = (image_info.height * percentage_to_fraction(region.y_pct)).round
"#{region.width_pct}%x#{region.height_pct}+#{offset_x}+#{offset_y}"
end

# @return [Integer] the height in pixels
def height
image_info.height
end
def kakadu_percent
offset_x = (image_info.width * percentage_to_fraction(region.x_pct)).round
offset_y = (image_info.height * percentage_to_fraction(region.y_pct)).round
"\{#{decimal_offset_y(offset_y)},#{decimal_offset_x(offset_x)}\}," \
"\{#{percentage_to_fraction(region.height_pct)},#{percentage_to_fraction(region.width_pct)}\}"
end

# @return [Integer] the width in pixels
def width
image_info.width
end
def kakadu_square
min, max = [image_info.width, image_info.height].minmax
offset = (max - min) / 2
if image_info.height >= image_info.width
# Portrait
"\{#{decimal_height(offset)},0\}," \
"\{#{decimal_height(image_info.height)},#{decimal_width(image_info.height)}\}"
else
# Landscape
"\{0,#{decimal_width(offset)}\}," \
"\{#{decimal_height(image_info.width)},#{decimal_width(image_info.width)}\}"
end
end

# @return [Float] the fractional height with respect to the original size
def decimal_height(n = height)
n.to_f / image_info.height
end
def imagemagick_square
min, max = [image_info.width, image_info.height].minmax
offset = (max - min) / 2
if image_info.height >= image_info.width
"#{min}x#{min}+0+#{offset}"
else
"#{min}x#{min}+#{offset}+0"
end
end

# @return [Float] the fractional width with respect to the original size
def decimal_width(n = width)
n.to_f / image_info.width
end
# @return [Integer] the height in pixels
def height
image_info.height
end

def decimal_offset_x
offset_x.to_f / image_info.width
end
# @return [Integer] the width in pixels
def width
image_info.width
end

def decimal_offset_y
offset_y.to_f / image_info.height
end
# @return [Float] the fractional height with respect to the original size
def decimal_height(n = height)
n.to_f / image_info.height
end

def maintain_aspect_ratio?
(height / width) == (image_info.height / image_info.width)
end
# @return [Float] the fractional width with respect to the original size
def decimal_width(n = width)
n.to_f / image_info.width
end

def decimal_offset_x(offset_x)
offset_x.to_f / image_info.width
end

def decimal_offset_y(offset_y)
offset_y.to_f / image_info.height
end

def maintain_aspect_ratio?
(height / width) == (image_info.height / image_info.width)
end

def percentage_to_fraction(n)
n / 100.0
end
end
end
7 changes: 4 additions & 3 deletions app/services/riiif/imagemagick_command_factory.rb
Original file line number Diff line number Diff line change
Expand Up @@ -54,17 +54,18 @@ def output
end

def crop
directive = transformation.crop.to_imagemagick
directive = Crop.new(transformation.region, info).to_imagemagick
" -crop #{directive}" if directive
end

def size
directive = transformation.size.to_imagemagick
directive = Resize.new(transformation.size, info).to_imagemagick
" -resize #{directive}" if directive
end

def rotation
" -virtual-pixel white +distort srt #{transformation.rotation}" if transformation.rotation
return if transformation.rotation.zero?
" -virtual-pixel white +distort srt #{transformation.rotation}"
end

def quality
Expand Down
4 changes: 2 additions & 2 deletions app/services/riiif/kakadu_command_factory.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ def command(tmp_file)
end

def reduction_factor
@reduction_factor ||= transformation.size.reduction_factor
@reduction_factor ||= Resize.new(transformation.size, info).reduction_factor
end

private
Expand All @@ -47,7 +47,7 @@ def quiet
end

def region
region_arg = transformation.crop.to_kakadu
region_arg = Crop.new(transformation.region, info).to_kakadu
" -region \"#{region_arg}\"" if region_arg
end

Expand Down
Loading

0 comments on commit 6acf20d

Please sign in to comment.