riiif 2.0.0.beta2 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. checksums.yaml +5 -5
  2. data/.rubocop.yml +2 -11
  3. data/.rubocop_todo.yml +76 -33
  4. data/README.md +17 -2
  5. data/app/controllers/riiif/images_controller.rb +8 -2
  6. data/app/models/riiif/image.rb +15 -20
  7. data/app/models/riiif/image_information.rb +12 -24
  8. data/app/services/riiif/crop.rb +99 -30
  9. data/app/services/riiif/image_magick_info_extractor.rb +9 -2
  10. data/app/services/riiif/imagemagick_command_factory.rb +9 -4
  11. data/app/services/riiif/kakadu_command_factory.rb +2 -2
  12. data/app/services/riiif/resize.rb +72 -7
  13. data/app/transformers/riiif/kakadu_transformer.rb +25 -2
  14. data/docs/benchmark.md +75 -0
  15. data/lib/riiif/engine.rb +2 -1
  16. data/lib/riiif/routes.rb +3 -0
  17. data/lib/riiif/version.rb +1 -1
  18. data/riiif.gemspec +3 -3
  19. data/spec/controllers/riiif/images_controller_spec.rb +14 -3
  20. data/spec/models/riiif/image_information_spec.rb +2 -10
  21. data/spec/models/riiif/image_spec.rb +10 -16
  22. data/spec/services/riiif/imagemagick_command_factory_spec.rb +6 -6
  23. data/spec/services/riiif/kakadu_command_factory_spec.rb +15 -15
  24. data/spec/transformers/riiif/kakadu_transformer_spec.rb +22 -22
  25. metadata +24 -46
  26. data/app/models/riiif/transformation.rb +0 -35
  27. data/app/services/riiif/imagemagick_transformer.rb +0 -8
  28. data/app/services/riiif/option_decoder.rb +0 -88
  29. data/app/services/riiif/region/absolute.rb +0 -23
  30. data/app/services/riiif/region/full.rb +0 -23
  31. data/app/services/riiif/region/percentage.rb +0 -68
  32. data/app/services/riiif/region/square.rb +0 -45
  33. data/app/services/riiif/size/absolute.rb +0 -39
  34. data/app/services/riiif/size/best_fit.rb +0 -18
  35. data/app/services/riiif/size/full.rb +0 -17
  36. data/app/services/riiif/size/height.rb +0 -24
  37. data/app/services/riiif/size/percent.rb +0 -44
  38. data/app/services/riiif/size/width.rb +0 -24
  39. data/spec/models/riiif/transformation_spec.rb +0 -42
  40. data/spec/services/riiif/region/absolute_spec.rb +0 -17
  41. data/spec/services/riiif/size/absolute_spec.rb +0 -17
  42. data/spec/services/riiif/size/height_spec.rb +0 -13
  43. data/spec/services/riiif/size/width_spec.rb +0 -13
@@ -1,23 +0,0 @@
1
- module Riiif
2
- module Region
3
- # Represents an absolute specified region
4
- class Absolute < Crop
5
- # TODO: only kakadu needs image_info. So there's potenial to optimize by
6
- # making image_info a proxy that fetches the info lazily when needed.
7
- # @param [ImageInformation] image_info
8
- # @param [String] x
9
- # @param [String] y
10
- # @param [String] width
11
- # @param [String] height
12
- def initialize(image_info, x, y, width, height)
13
- @image_info = image_info
14
- @offset_x = x.to_i
15
- @offset_y = y.to_i
16
- @width = width.to_i
17
- @height = height.to_i
18
- end
19
-
20
- attr_reader :width, :height
21
- end
22
- end
23
- end
@@ -1,23 +0,0 @@
1
- module Riiif
2
- module Region
3
- # Represents the image or region requested at its full size.
4
- # This is a nil crop operation.
5
- class Full < Crop
6
- def initialize(image_info)
7
- @image_info = image_info
8
- end
9
-
10
- # @return [NilClass] a region for imagemagick to decode
11
- # the nil implies no cropping needed
12
- def to_imagemagick
13
- nil
14
- end
15
-
16
- # @return [NilClass] a region for kakadu to decode
17
- # the nil implies no cropping needed
18
- def to_kakadu
19
- nil
20
- end
21
- end
22
- end
23
- end
@@ -1,68 +0,0 @@
1
- module Riiif
2
- module Region
3
- # represents request cooridnates specified as percentage
4
- class Percentage < Crop
5
- def initialize(image_info, x, y, width, height)
6
- @image_info = image_info
7
- @x_pct = x
8
- @y_pct = y
9
- @width_pct = width
10
- @height_pct = height
11
- end
12
-
13
- # From the Imagemagick docs:
14
- # The percentage symbol '%' can appear anywhere in a argument, and if
15
- # given will refer to both width and height numbers. It is a flag that
16
- # just declares that the 'image size' parts are a percentage fraction
17
- # of the images virtual canvas or page size. Offsets are always given
18
- # in pixels.
19
- # @return [String] a region for imagemagick to decode
20
- # (appropriate for passing to the -crop parameter)
21
- def to_imagemagick
22
- "#{@width_pct}%x#{@height_pct}+#{offset_x}+#{offset_y}"
23
- end
24
-
25
- def maintain_aspect_ratio?
26
- @width_pct == @height_pct
27
- end
28
-
29
- private
30
-
31
- # @param [String] n a percentage to convert
32
- # @return [Float]
33
- def percentage_to_fraction(n)
34
- Integer(n).to_f / 100
35
- end
36
-
37
- # @return [Integer]
38
- def offset_x
39
- (@image_info.width * percentage_to_fraction(@x_pct)).round
40
- end
41
-
42
- # @return [Integer]
43
- def offset_y
44
- (@image_info.height * percentage_to_fraction(@y_pct)).round
45
- end
46
-
47
- # @return [Float]
48
- def decimal_height
49
- percentage_to_fraction(@height_pct)
50
- end
51
-
52
- # @return [Float]
53
- def decimal_width
54
- percentage_to_fraction(@width_pct)
55
- end
56
-
57
- # @return [Float]
58
- def decimal_offset_y
59
- percentage_to_fraction(@y_pct)
60
- end
61
-
62
- # @return [Float]
63
- def decimal_offset_x
64
- percentage_to_fraction(@x_pct)
65
- end
66
- end
67
- end
68
- end
@@ -1,45 +0,0 @@
1
- module Riiif
2
- module Region
3
- # Represents requested square cooridnates
4
- class Square < Crop
5
- def initialize(image_info)
6
- @image_info = image_info
7
- @min, @max = [@image_info.width, @image_info.height].minmax
8
- @offset = (@max - @min) / 2
9
- end
10
-
11
- # @return [String] a square region for imagemagick to decode
12
- # (appropriate for passing to the -crop parameter)
13
- def to_imagemagick
14
- if @image_info.height >= @image_info.width
15
- "#{height}x#{width}+0+#{@offset}"
16
- else
17
- "#{height}x#{width}+#{@offset}+0"
18
- end
19
- end
20
-
21
- # @return [String] a region for kakadu to decode
22
- # (appropriate for passing to the -region parameter)
23
- def to_kakadu
24
- # (top, left, height, width)
25
- if @image_info.height >= @image_info.width
26
- # Portrait
27
- "\{#{decimal_height(@offset)},0\}," \
28
- "\{#{decimal_height(height)},#{decimal_width(height)}\}"
29
- else
30
- # Landscape
31
- "\{0,#{decimal_width(@offset)}\}," \
32
- "\{#{decimal_height(width)},#{decimal_width(width)}\}"
33
- end
34
- end
35
-
36
- def height
37
- @min
38
- end
39
-
40
- def width
41
- @min
42
- end
43
- end
44
- end
45
- end
@@ -1,39 +0,0 @@
1
- module Riiif
2
- module Size
3
- # The width and height of the returned image are exactly w and h.
4
- # The aspect ratio of the returned image may be different than the extracted
5
- # region, resulting in a distorted image.
6
- class Absolute < Resize
7
- # @param [ImageInformation] info
8
- # @param [String] width
9
- # @param [String] height
10
- def initialize(info, width, height)
11
- @image_info = info
12
- @width = width.to_i
13
- @height = height.to_i
14
- end
15
-
16
- # @return [String] a resize directive for imagemagick to use
17
- def to_imagemagick
18
- "#{@width}x#{@height}!"
19
- end
20
-
21
- attr_reader :height, :width
22
-
23
- # Reduce this if the aspect ratio of the image is maintained.
24
- def reduce?
25
- in_delta?(image_info.aspect_ratio, aspect_ratio, 0.001)
26
- end
27
-
28
- private
29
-
30
- def aspect_ratio
31
- width.to_f / height
32
- end
33
-
34
- def in_delta?(x1, x2, delta)
35
- (x1 - x2).abs <= delta
36
- end
37
- end
38
- end
39
- end
@@ -1,18 +0,0 @@
1
- module Riiif
2
- module Size
3
- # The image content is scaled for the best fit such that the resulting width and
4
- # height are less than or equal to the requested width and height.
5
- class BestFit < Resize
6
- def initialize(info, width, height)
7
- @image_info = info
8
- @width = width
9
- @height = height
10
- end
11
-
12
- # @return [String] a resize directive for imagemagick to use
13
- def to_imagemagick
14
- "#{@width}x#{@height}"
15
- end
16
- end
17
- end
18
- end
@@ -1,17 +0,0 @@
1
- module Riiif
2
- module Size
3
- # represents requested full size
4
- class Full < Resize
5
- # @return [NilClass] a size for imagemagick to decode
6
- # the nil implies no resizing needed
7
- def to_imagemagick
8
- nil
9
- end
10
-
11
- # Should we reduce this image?
12
- def reduce?
13
- false
14
- end
15
- end
16
- end
17
- end
@@ -1,24 +0,0 @@
1
- module Riiif
2
- module Size
3
- # The image or region should be scaled so that its height is exactly equal
4
- # to the provided parameter, and the width will be a calculated value that
5
- # maintains the aspect ratio of the extracted region
6
- class Height < Resize
7
- def initialize(info, height)
8
- @image_info = info
9
- @height = height.to_i
10
- end
11
-
12
- # @return [String] a resize directive for imagemagick to use
13
- def to_imagemagick
14
- "x#{@height}"
15
- end
16
-
17
- def width
18
- height * image_info.width / image_info.height
19
- end
20
-
21
- attr_reader :height
22
- end
23
- end
24
- end
@@ -1,44 +0,0 @@
1
- module Riiif
2
- module Size
3
- # The width and height of the returned image is scaled to n% of the width and height
4
- # of the extracted region. The aspect ratio of the returned image is the same as that
5
- # of the extracted region.
6
- class Percent < Resize
7
- def initialize(info, percentage)
8
- @image_info = info
9
- @percentage = percentage
10
- end
11
-
12
- attr_reader :percentage
13
-
14
- # @return [String] a resize directive for imagemagick to use
15
- def to_imagemagick
16
- "#{percentage}%"
17
- end
18
-
19
- # @return [Integer] the height in pixels
20
- def height
21
- percent_of(image_info.height)
22
- end
23
-
24
- # @return [Integer] the width in pixels
25
- def width
26
- percent_of(image_info.width)
27
- end
28
-
29
- # @param [Integer] factor number of times to reduce by 1/2
30
- def reduce(factor)
31
- pct = percentage.to_f * 2**factor
32
- Percent.new(image_info, pct)
33
- end
34
-
35
- private
36
-
37
- # @param [Integer] value a value to convert to the percentage
38
- # @return [Float]
39
- def percent_of(value)
40
- value * Integer(percentage).to_f / 100
41
- end
42
- end
43
- end
44
- end
@@ -1,24 +0,0 @@
1
- module Riiif
2
- module Size
3
- # The image or region should be scaled so that its width is exactly equal
4
- # to the provided parameter, and the height will be a calculated value that
5
- # maintains the aspect ratio of the extracted region
6
- class Width < Resize
7
- def initialize(info, width)
8
- @image_info = info
9
- @width = width.to_i
10
- end
11
-
12
- # @return [String] a resize directive for imagemagick to use
13
- def to_imagemagick
14
- @width.to_s
15
- end
16
-
17
- attr_reader :width
18
-
19
- def height
20
- width * image_info.height / image_info.width
21
- end
22
- end
23
- end
24
- end
@@ -1,42 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'spec_helper'
4
-
5
- RSpec.describe Riiif::Transformation do
6
- subject(:transformation) do
7
- Riiif::Transformation.new(region,
8
- size,
9
- quality,
10
- rotation,
11
- fmt)
12
- end
13
-
14
- let(:region) { Riiif::Region::Full.new(image_info) }
15
- let(:size) { Riiif::Size::Percent.new(image_info, 20) }
16
- let(:quality) { nil }
17
- let(:rotation) { nil }
18
- let(:fmt) { nil }
19
- let(:image_info) { double('Image info', height: 4381, width: 6501) }
20
-
21
- describe 'reduce' do
22
- subject { transformation.reduce(factor) }
23
- context 'when reduced by 2' do
24
- let(:factor) { 2 }
25
- let(:size) { Riiif::Size::Percent.new(image_info, 20) }
26
-
27
- it 'downsamples the size' do
28
- expect(subject.size).to be_kind_of Riiif::Size::Percent
29
- expect(subject.size.percentage).to eq 80.0
30
- end
31
- end
32
- end
33
-
34
- describe 'without_crop' do
35
- let(:region) { Riiif::Region::Absolute.new(image_info, 5, 6, 7, 8) }
36
-
37
- subject { transformation.without_crop(image_info) }
38
- it 'nullifies the crop' do
39
- expect(subject.crop).to be_kind_of Riiif::Region::Full
40
- end
41
- end
42
- end
@@ -1,17 +0,0 @@
1
- require 'spec_helper'
2
-
3
- RSpec.describe Riiif::Region::Absolute do
4
- let(:image_info) { double }
5
-
6
- context 'when initialized with strings' do
7
- let(:instance) { described_class.new(image_info, '5', '15', '50', '100') }
8
-
9
- it 'casts height to an integer' do
10
- expect(instance.height).to eq 100
11
- end
12
-
13
- it 'casts width to an integer' do
14
- expect(instance.width).to eq 50
15
- end
16
- end
17
- end
@@ -1,17 +0,0 @@
1
- require 'spec_helper'
2
-
3
- RSpec.describe Riiif::Size::Absolute do
4
- let(:image_info) { double }
5
-
6
- context 'when initialized with strings' do
7
- let(:instance) { described_class.new(image_info, '50', '100') }
8
-
9
- it 'casts height to an integer' do
10
- expect(instance.height).to eq 100
11
- end
12
-
13
- it 'casts width to an integer' do
14
- expect(instance.width).to eq 50
15
- end
16
- end
17
- end
@@ -1,13 +0,0 @@
1
- require 'spec_helper'
2
-
3
- RSpec.describe Riiif::Size::Height do
4
- let(:image_info) { double }
5
-
6
- context 'when initialized with strings' do
7
- let(:instance) { described_class.new(image_info, '50') }
8
-
9
- it 'casts height to an integer' do
10
- expect(instance.height).to eq 50
11
- end
12
- end
13
- end
@@ -1,13 +0,0 @@
1
- require 'spec_helper'
2
-
3
- RSpec.describe Riiif::Size::Width do
4
- let(:image_info) { double }
5
-
6
- context 'when initialized with strings' do
7
- let(:instance) { described_class.new(image_info, '50') }
8
-
9
- it 'casts height to an integer' do
10
- expect(instance.width).to eq 50
11
- end
12
- end
13
- end