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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0b9d709cf8f472296f8feafaf8d54a14201fd86b25fb2dfee1f20e0e0994fdaa
4
- data.tar.gz: 8ec9471abc118d5d13e661a86ab403695285cb4996b4f2cd47849cd9830a5e19
3
+ metadata.gz: 92c92a32465d8ae59f5e40a31c0ffd3cc2de271a3593db0dac7da1bd2954dd31
4
+ data.tar.gz: 044b86d16c8c028d36864e3aa550b6aa871d9075c5d4223b198ca1ac59b511f2
5
5
  SHA512:
6
- metadata.gz: 5f9a648001fda8a468914b787eb04218bbc2b6c96f4e0ef3bb5331b0e76e2b4285eb9df76c7c66d47151f38a4064676a84ceada530c445b48343d92701aab809
7
- data.tar.gz: c35f17d9c6e90732c721fff635684103e5779c0b313f1e9186ecb0dd677b960de4aa7d03daa33b537453e0290788cb9bf6ca332166b792724e139633a91cb8e9
6
+ metadata.gz: dc4ae61808bb12ad97f4f3a279aa81fd048b20626422358ccfc64ed1c5706d221a97195a0807dcd882c32dbfbd8ced6fba06bfe9e361ae61abfd6a1a38aed5a2
7
+ data.tar.gz: d416dd8390d144135bf5d1e4d9dc5445d0f137a6e64ce097aef8fe2e5f895214a18a4f5fd064f874ead2928db969b5dbc92fbe5a86ac20c244e199c6bca93757
@@ -1,23 +1,27 @@
1
1
  module Imogen
2
- module Iiif
3
- class Rotation < Transform
4
- RIGHT_ANGLES = [0,90,180,270]
5
- def get(rotate)
6
- return nil if [nil, 0, '0'].include?(rotate)
7
- raise BadRequest.new("bad rotate #{rotate}") unless rotate.to_s =~ /^-?\d+$/
8
- # libvips and IIIF spec counts clockwise
9
- r = rotate.to_i % 360
10
- raise BadRequest.new("bad rotate #{rotate}") unless RIGHT_ANGLES.include? r
11
- return r > 0 ? r : nil
12
- end
13
- def self.convert(img, rotate)
14
- rotation = Rotation.new(img).get(rotate)
15
- if rotation
16
- yield img.rot("d#{rotation}")
17
- else
18
- yield img
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
- before(:all) do
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 nil for 0 or '0' or nil" do
11
- expect(subject.get(0)).to be_nil
12
- expect(subject.get(360)).to be_nil
13
- expect(subject.get("360")).to be_nil
14
- expect(subject.get("-360")).to be_nil
15
- expect(subject.get("0")).to be_nil
16
- expect(subject.get(nil)).to be_nil
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
- # IIIF rotation is opposite FreeImage
19
- it "should calculate for positive values" do
20
- expect(subject.get(90)).to eql(90)
21
- expect(subject.get("90")).to eql(90)
22
- expect(subject.get("180")).to eql(180)
23
- expect(subject.get("270")).to eql(270)
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
- # IIIF rotation is opposite FreeImage
27
- it "should calculate for negative values" do
28
- expect(subject.get(-90)).to eql(270)
29
- expect(subject.get("-90")).to eql(270)
30
- expect(subject.get("-180")).to eql(180)
31
- expect(subject.get("-270")).to eql(90)
32
- expect(subject.get("-450")).to eql(270)
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.0
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ben Armintor
8
- autorequire:
8
+ - Eric O'Hanlon
9
+ autorequire:
9
10
  bindir: bin
10
11
  cert_chain: []
11
- date: 2019-11-08 00:00:00.000000000 Z
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.6
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: []