imogen 0.2.0 → 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/imogen/iiif/rotation.rb +23 -19
- data/spec/integration/imogen_iiif_spec.rb +1 -1
- data/spec/spec_helper.rb +7 -7
- data/spec/unit/imogen_iiif_rotate_spec.rb +58 -25
- metadata +8 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 92c92a32465d8ae59f5e40a31c0ffd3cc2de271a3593db0dac7da1bd2954dd31
|
4
|
+
data.tar.gz: 044b86d16c8c028d36864e3aa550b6aa871d9075c5d4223b198ca1ac59b511f2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: dc4ae61808bb12ad97f4f3a279aa81fd048b20626422358ccfc64ed1c5706d221a97195a0807dcd882c32dbfbd8ced6fba06bfe9e361ae61abfd6a1a38aed5a2
|
7
|
+
data.tar.gz: d416dd8390d144135bf5d1e4d9dc5445d0f137a6e64ce097aef8fe2e5f895214a18a4f5fd064f874ead2928db969b5dbc92fbe5a86ac20c244e199c6bca93757
|
data/lib/imogen/iiif/rotation.rb
CHANGED
@@ -1,23 +1,27 @@
|
|
1
1
|
module Imogen
|
2
|
-
module Iiif
|
3
|
-
class Rotation < Transform
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
2
|
+
module Iiif
|
3
|
+
class Rotation < Transform
|
4
|
+
RIGHT_ANGLES = [0,90,180,270]
|
5
|
+
def get(rotate)
|
6
|
+
return [0, false] if rotate.nil?
|
7
|
+
original_rotate_value = rotate
|
8
|
+
rotate = rotate.to_s
|
9
|
+
raise BadRequest.new("bad rotate #{original_rotate_value}") unless rotate =~ /^!?-?\d+$/
|
10
|
+
flip = rotate.to_s.start_with?('!')
|
11
|
+
# libvips and IIIF spec counts clockwise
|
12
|
+
angle = rotate.sub(/^!/, '').to_i % 360
|
13
|
+
raise BadRequest.new("bad rotate #{original_rotate_value}") unless RIGHT_ANGLES.include?(angle)
|
14
|
+
return angle, flip
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.convert(img, rotate)
|
18
|
+
angle, flip = Rotation.new(img).get(rotate)
|
19
|
+
# IIIF spec applies horizontal flip ("mirrored by reflection on the vertical axis") before rotation
|
20
|
+
img = img.fliphor if flip
|
21
|
+
# No need to rotate if angle is zero
|
22
|
+
img = img.rot("d#{angle}") unless angle.zero?
|
23
|
+
yield img
|
24
|
+
end
|
19
25
|
end
|
20
26
|
end
|
21
27
|
end
|
22
|
-
end
|
23
|
-
end
|
@@ -6,7 +6,7 @@ describe Imogen::AutoCrop, vips: true do
|
|
6
6
|
let(:output_file) { Dir.tmpdir + '/test-imogen-convert.jpg' }
|
7
7
|
it "should successfully convert the image" do
|
8
8
|
Imogen.with_image(fixture('sample.jpg').path) do |img|
|
9
|
-
Imogen::Iiif.convert(img, output_file, 'jpg', region: '50,60,500,800', size: '!100,100', quality: 'color', rotation: 90)
|
9
|
+
Imogen::Iiif.convert(img, output_file, 'jpg', region: '50,60,500,800', size: '!100,100', quality: 'color', rotation: '!90')
|
10
10
|
end
|
11
11
|
expect(File.exist?(output_file)).to be true
|
12
12
|
expect(File.size?(output_file)).to be > 0
|
data/spec/spec_helper.rb
CHANGED
@@ -47,13 +47,6 @@ RSpec.configure do |config|
|
|
47
47
|
# The settings below are suggested to provide a good initial experience
|
48
48
|
# with RSpec, but feel free to customize to your heart's content.
|
49
49
|
=begin
|
50
|
-
# This allows you to limit a spec run to individual examples or groups
|
51
|
-
# you care about by tagging them with `:focus` metadata. When nothing
|
52
|
-
# is tagged with `:focus`, all examples get run. RSpec also provides
|
53
|
-
# aliases for `it`, `describe`, and `context` that include `:focus`
|
54
|
-
# metadata: `fit`, `fdescribe` and `fcontext`, respectively.
|
55
|
-
config.filter_run_when_matching :focus
|
56
|
-
|
57
50
|
# Allows RSpec to persist some state between runs in order to support
|
58
51
|
# the `--only-failures` and `--next-failure` CLI options. We recommend
|
59
52
|
# you configure your source control system to ignore this file.
|
@@ -97,6 +90,13 @@ RSpec.configure do |config|
|
|
97
90
|
# as the one that triggered the failure.
|
98
91
|
Kernel.srand config.seed
|
99
92
|
=end
|
93
|
+
|
94
|
+
# This allows you to limit a spec run to individual examples or groups
|
95
|
+
# you care about by tagging them with `:focus` metadata. When nothing
|
96
|
+
# is tagged with `:focus`, all examples get run. RSpec also provides
|
97
|
+
# aliases for `it`, `describe`, and `context` that include `:focus`
|
98
|
+
# metadata: `fit`, `fdescribe` and `fcontext`, respectively.
|
99
|
+
config.filter_run_when_matching :focus
|
100
100
|
end
|
101
101
|
|
102
102
|
class ImageStub
|
@@ -1,35 +1,41 @@
|
|
1
1
|
require 'imogen/iiif'
|
2
2
|
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
3
3
|
describe Imogen::Iiif::Rotation, type: :unit do
|
4
|
-
|
5
|
-
@test_image = ImageStub.new(175,131)
|
6
|
-
end
|
7
|
-
subject {Imogen::Iiif::Rotation.new(@test_image)}
|
4
|
+
let(:image) { double("image", width: 175, height: 131) }
|
8
5
|
describe "#get" do
|
6
|
+
subject { Imogen::Iiif::Rotation.new(image) }
|
9
7
|
describe "with values mod 360 in 90 degree rotations" do
|
10
|
-
it "should
|
11
|
-
expect(subject.get(0)).to
|
12
|
-
expect(subject.get(360)).to
|
13
|
-
expect(subject.get("360")).to
|
14
|
-
expect(subject.get("-360")).to
|
15
|
-
expect(subject.get("0")).to
|
16
|
-
expect(subject.get(nil)).to
|
8
|
+
it "should return [0, false] angle and flip for 0 or '0' or nil" do
|
9
|
+
expect(subject.get(0)).to eq([0, false])
|
10
|
+
expect(subject.get(360)).to eq([0, false])
|
11
|
+
expect(subject.get("360")).to eq([0, false])
|
12
|
+
expect(subject.get("-360")).to eq([0, false])
|
13
|
+
expect(subject.get("0")).to eq([0, false])
|
14
|
+
expect(subject.get(nil)).to eq([0, false])
|
15
|
+
end
|
16
|
+
it "should return the expected angle and flip for positive values" do
|
17
|
+
expect(subject.get(90)).to eql([90, false])
|
18
|
+
expect(subject.get("90")).to eql([90, false])
|
19
|
+
expect(subject.get("180")).to eql([180, false])
|
20
|
+
expect(subject.get("270")).to eql([270, false])
|
21
|
+
expect(subject.get("450")).to eql([90, false])
|
17
22
|
end
|
18
|
-
|
19
|
-
|
20
|
-
expect(subject.get(90)).to eql(
|
21
|
-
expect(subject.get("
|
22
|
-
expect(subject.get("
|
23
|
-
expect(subject.get("
|
24
|
-
expect(subject.get("450")).to eql(90)
|
23
|
+
it "should return the expected angle and flip for negative values" do
|
24
|
+
expect(subject.get(-90)).to eql([270, false])
|
25
|
+
expect(subject.get("-90")).to eql([270, false])
|
26
|
+
expect(subject.get("-180")).to eql([180, false])
|
27
|
+
expect(subject.get("-270")).to eql([90, false])
|
28
|
+
expect(subject.get("-450")).to eql([270, false])
|
25
29
|
end
|
26
|
-
|
27
|
-
|
28
|
-
expect(subject.get(
|
29
|
-
expect(subject.get("
|
30
|
-
expect(subject.get("
|
31
|
-
expect(subject.get("
|
32
|
-
expect(subject.get("
|
30
|
+
it "should return the expected angle and flip for string values that start with an exclamation point" do
|
31
|
+
expect(subject.get("!0")).to eql([0, true])
|
32
|
+
expect(subject.get("!90")).to eql([90, true])
|
33
|
+
expect(subject.get("!180")).to eql([180, true])
|
34
|
+
expect(subject.get("!270")).to eql([270, true])
|
35
|
+
expect(subject.get("!-90")).to eql([270, true])
|
36
|
+
expect(subject.get("!-180")).to eql([180, true])
|
37
|
+
expect(subject.get("!-270")).to eql([90, true])
|
38
|
+
expect(subject.get("!-450")).to eql([270, true])
|
33
39
|
end
|
34
40
|
end
|
35
41
|
it "should reject arbitrary integer and float values" do
|
@@ -41,4 +47,31 @@ describe Imogen::Iiif::Rotation, type: :unit do
|
|
41
47
|
expect{subject.get("-2,")}.to raise_error Imogen::Iiif::BadRequest
|
42
48
|
end
|
43
49
|
end
|
50
|
+
describe '.convert' do
|
51
|
+
let(:no_op) { Proc.new {|x| x} }
|
52
|
+
context 'at multiple of 360' do
|
53
|
+
it "does not rotate" do
|
54
|
+
expect(image).not_to receive(:rot)
|
55
|
+
expect(image).not_to receive(:fliphor)
|
56
|
+
(-2..2).each { |x| described_class.convert(image, (x*360).to_s, &no_op) }
|
57
|
+
end
|
58
|
+
end
|
59
|
+
context 'at right angle rotations not multiple of 360' do
|
60
|
+
it "does rotate" do
|
61
|
+
expect(image).not_to receive(:fliphor)
|
62
|
+
[-3, -2, -1, 1, 2, 3].each do |x|
|
63
|
+
tuple = Imogen::Iiif::Rotation.new(image).get((90*x).to_s)
|
64
|
+
param = "d#{tuple[0]}"
|
65
|
+
expect(image).to receive(:rot).with(param)
|
66
|
+
described_class.convert(image, (x*90).to_s, &no_op)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
context 'with a bang param' do
|
71
|
+
it "flips horizontal" do
|
72
|
+
expect(image).to receive(:fliphor)
|
73
|
+
described_class.convert(image, "!0", &no_op)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
44
77
|
end
|
metadata
CHANGED
@@ -1,14 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: imogen
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ben Armintor
|
8
|
-
|
8
|
+
- Eric O'Hanlon
|
9
|
+
autorequire:
|
9
10
|
bindir: bin
|
10
11
|
cert_chain: []
|
11
|
-
date:
|
12
|
+
date: 2021-02-26 00:00:00.000000000 Z
|
12
13
|
dependencies:
|
13
14
|
- !ruby/object:Gem::Dependency
|
14
15
|
name: ruby-vips
|
@@ -52,7 +53,7 @@ dependencies:
|
|
52
53
|
- - "~>"
|
53
54
|
- !ruby/object:Gem::Version
|
54
55
|
version: '3.9'
|
55
|
-
description:
|
56
|
+
description:
|
56
57
|
email: armintor@gmail.com
|
57
58
|
executables: []
|
58
59
|
extensions: []
|
@@ -80,7 +81,7 @@ files:
|
|
80
81
|
homepage: https://github.com/cul/imogen
|
81
82
|
licenses: []
|
82
83
|
metadata: {}
|
83
|
-
post_install_message:
|
84
|
+
post_install_message:
|
84
85
|
rdoc_options: []
|
85
86
|
require_paths:
|
86
87
|
- lib
|
@@ -95,8 +96,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
95
96
|
- !ruby/object:Gem::Version
|
96
97
|
version: '0'
|
97
98
|
requirements: []
|
98
|
-
rubygems_version: 3.0.
|
99
|
-
signing_key:
|
99
|
+
rubygems_version: 3.0.8
|
100
|
+
signing_key:
|
100
101
|
specification_version: 4
|
101
102
|
summary: IIIF image derivative generation helpers for Vips
|
102
103
|
test_files: []
|