riiif 1.3.0 → 1.4.0

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
  SHA1:
3
- metadata.gz: 6b8dc5c1ffd5532b680b26ff6958a02261700d3e
4
- data.tar.gz: 7719e41b21ee91d52eefe4cd5347fb87db25b47c
3
+ metadata.gz: 0aaf0ae50831c1b402852fee520e6a4a0c9b8760
4
+ data.tar.gz: 141b672ec9ce926ae80d139febb926a82d607cc2
5
5
  SHA512:
6
- metadata.gz: 453bd022c4fb48291f987625db7c22d6709a7997bb26d9123da975b6ab7537776d847a7d618369788e3e756e08770a99aa29496126540a75a9ed1516b0666814
7
- data.tar.gz: 1b96e14965119ee2454f3a44a144b572643af01a00616eff0e5b76fd1a604b1b58ed6f2185d02c33ba811cd8975baa9c8f68ab9c09c2a4139fe4d8e520810342
6
+ metadata.gz: 3729b7972bea7cfea2d4f1c21b75ad3c974b54c2307a1ab63e297a7b06cf5e5dc9efb9bc919a6c8b5c3e7d04dc9030866e10e2c0fc368dc8a2b1bc4518dd0b4f
7
+ data.tar.gz: ee0acb8006038a89caceb49cd4216ce08d3f65136ca38f5aff3ed2391bd0fb17ced7a48075e7f65565d3d0b600f199c004d2ee0e027b0ad80f3ff9ba48ecf338
@@ -16,7 +16,7 @@ module Riiif
16
16
  stdout.close
17
17
  err = stderr.read
18
18
  stderr.close
19
- raise "Unable to execute command \"#{command}\"\n#{err}" unless wait_thr.value.success?
19
+ raise ConversionError, "Unable to execute command \"#{command}\"\n#{err}" unless wait_thr.value.success?
20
20
  end
21
21
  out
22
22
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Riiif
2
4
  # Builds a command to run a transformation using Imagemagick
3
5
  class ImagemagickCommandFactory
@@ -5,48 +7,84 @@ module Riiif
5
7
  # @param [String] path the location of the file
6
8
  # @param [Transformation] transformation
7
9
  # @param [Integer] compression (85) the compression level to use (set 0 for no compression)
10
+ # @param [String] sampling_factor ("4:2:0") the chroma sample factor (set 0 for no compression)
11
+ # @param [Boolean] strip_metadata (true) do we want to strip EXIF tags?
8
12
  # @return [String] a command for running imagemagick to produce the requested output
9
- def self.build(path, transformation, compression: 85)
10
- new(path, transformation, compression: compression).build
13
+ def self.build(path, transformation, compression: 85, sampling_factor: '4:2:0', strip_metadata: true)
14
+ new(path, transformation,
15
+ compression: compression,
16
+ sampling_factor: sampling_factor,
17
+ strip_metadata: strip_metadata).build
11
18
  end
12
19
 
13
20
  # A helper method to instantiate and invoke build
14
21
  # @param [String] path the location of the file
15
22
  # @param [Transformation] transformation
16
23
  # @param [Integer] compression the compression level to use (set 0 for no compression)
17
- def initialize(path, transformation, compression:)
24
+ def initialize(path, transformation, compression:, sampling_factor:, strip_metadata:)
18
25
  @path = path
19
26
  @transformation = transformation
20
27
  @compression = compression
28
+ @sampling_factor = sampling_factor
29
+ @strip_metadata = strip_metadata
21
30
  end
22
31
 
23
- attr_reader :path, :transformation, :compression
32
+ attr_reader :path, :transformation, :compression, :sampling_factor, :strip_metadata
24
33
 
25
34
  # @return [String] a command for running imagemagick to produce the requested output
26
35
  def build
27
- command = 'convert'
28
- command << " -crop #{transformation.crop}" if transformation.crop
29
- command << " -resize #{transformation.size}" if transformation.size
30
- if transformation.rotation
31
- command << " -virtual-pixel white +distort srt #{transformation.rotation}"
32
- end
33
-
34
- case transformation.quality
35
- when 'grey'
36
- command << ' -colorspace Gray'
37
- when 'bitonal'
38
- command << ' -colorspace Gray'
39
- command << ' -type Bilevel'
40
- end
41
- command << " -quality #{compression}" if use_compression?
42
- command << " #{path} #{transformation.format}:-"
43
- command
36
+ [command, crop, size, rotation, colorspace, quality, sampling, metadata, output].join
44
37
  end
45
38
 
46
39
  private
47
40
 
41
+ def command
42
+ 'convert'
43
+ end
44
+
48
45
  def use_compression?
49
- compression > 0 && transformation.format == 'jpg'
46
+ compression > 0 && jpeg?
47
+ end
48
+
49
+ def jpeg?
50
+ transformation.format == 'jpg'.freeze
51
+ end
52
+
53
+ def output
54
+ " #{path} #{transformation.format}:-"
55
+ end
56
+
57
+ def crop
58
+ " -crop #{transformation.crop}" if transformation.crop
59
+ end
60
+
61
+ def size
62
+ " -resize #{transformation.size}" if transformation.size
63
+ end
64
+
65
+ def rotation
66
+ " -virtual-pixel white +distort srt #{transformation.rotation}" if transformation.rotation
67
+ end
68
+
69
+ def quality
70
+ " -quality #{compression}" if use_compression?
71
+ end
72
+
73
+ def metadata
74
+ ' -strip' if strip_metadata
75
+ end
76
+
77
+ def sampling
78
+ " -sampling-factor #{sampling_factor}" if jpeg?
79
+ end
80
+
81
+ def colorspace
82
+ case transformation.quality
83
+ when 'grey'
84
+ ' -colorspace Gray'
85
+ when 'bitonal'
86
+ ' -colorspace Gray -type Bilevel'
87
+ end
50
88
  end
51
89
  end
52
90
  end
data/lib/riiif/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Riiif
2
- VERSION = '1.3.0'.freeze
2
+ VERSION = '1.4.0'.freeze
3
3
  end
data/lib/riiif.rb CHANGED
@@ -1,6 +1,5 @@
1
1
  require 'riiif/version'
2
2
  require 'riiif/engine'
3
-
4
3
  module Riiif
5
4
  extend ActiveSupport::Autoload
6
5
  autoload :Image
@@ -19,6 +18,8 @@ module Riiif
19
18
  @original_exception = orig
20
19
  end
21
20
  end
21
+ # This error is raised when Riiif can't convert an image
22
+ class ConversionError < Error; end
22
23
 
23
24
  Transformation = Struct.new(:crop, :size, :quality, :rotation, :format)
24
25
  ImageInformation = Struct.new(:width, :height)
@@ -6,7 +6,9 @@ RSpec.describe Riiif::Image do
6
6
  subject { described_class.new('world') }
7
7
  describe 'happy path' do
8
8
  before do
9
- expect(subject.image).to receive(:execute).with("convert -quality 85 #{filename} jpg:-").and_return('imagedata')
9
+ expect(subject.image).to receive(:execute)
10
+ .with("convert -quality 85 -sampling-factor 4:2:0 -strip #{filename} jpg:-")
11
+ .and_return('imagedata')
10
12
  end
11
13
  it 'renders' do
12
14
  expect(subject.render('size' => 'full', format: 'jpg')).to eq 'imagedata'
@@ -63,25 +65,25 @@ RSpec.describe Riiif::Image do
63
65
  describe 'mogrify' do
64
66
  describe 'region' do
65
67
  it 'returns the original when specifing full size' do
66
- expect(Riiif::CommandRunner).to receive(:execute).with("convert #{filename} png:-")
68
+ expect(Riiif::CommandRunner).to receive(:execute).with("convert -strip #{filename} png:-")
67
69
  subject.render(region: 'full', format: 'png')
68
70
  end
69
71
  it 'handles absolute geometry' do
70
- expect(Riiif::CommandRunner).to receive(:execute).with("convert -crop 60x75+80+15 #{filename} png:-")
72
+ expect(Riiif::CommandRunner).to receive(:execute).with("convert -crop 60x75+80+15 -strip #{filename} png:-")
71
73
  subject.render(region: '80,15,60,75', format: 'png')
72
74
  end
73
75
 
74
76
  it 'handles percent geometry' do
75
77
  expect(Riiif::CommandRunner).to receive(:execute)
76
78
  .with("identify -format %hx%w #{filename}").and_return('131x175')
77
- expect(Riiif::CommandRunner).to receive(:execute).with("convert -crop 80%x70+18+13 #{filename} png:-")
79
+ expect(Riiif::CommandRunner).to receive(:execute).with("convert -crop 80%x70+18+13 -strip #{filename} png:-")
78
80
  subject.render(region: 'pct:10,10,80,70', format: 'png')
79
81
  end
80
82
 
81
83
  it 'handles square geometry' do
82
84
  expect(Riiif::CommandRunner).to receive(:execute)
83
85
  .with("identify -format %hx%w #{filename}").and_return('131x175')
84
- expect(Riiif::CommandRunner).to receive(:execute).with("convert -crop 131x131+22+0 #{filename} png:-")
86
+ expect(Riiif::CommandRunner).to receive(:execute).with("convert -crop 131x131+22+0 -strip #{filename} png:-")
85
87
  subject.render(region: 'square', format: 'png')
86
88
  end
87
89
  it 'raises an error for invalid geometry' do
@@ -91,31 +93,31 @@ RSpec.describe Riiif::Image do
91
93
 
92
94
  describe 'resize' do
93
95
  it 'returns the original when specifing full size' do
94
- expect(Riiif::CommandRunner).to receive(:execute).with("convert #{filename} png:-")
96
+ expect(Riiif::CommandRunner).to receive(:execute).with("convert -strip #{filename} png:-")
95
97
  subject.render(size: 'full', format: 'png')
96
98
  end
97
99
  it 'handles integer percent sizes' do
98
- expect(Riiif::CommandRunner).to receive(:execute).with("convert -resize 50% #{filename} png:-")
100
+ expect(Riiif::CommandRunner).to receive(:execute).with("convert -resize 50% -strip #{filename} png:-")
99
101
  subject.render(size: 'pct:50', format: 'png')
100
102
  end
101
103
  it 'handles float percent sizes' do
102
- expect(Riiif::CommandRunner).to receive(:execute).with("convert -resize 12.5% #{filename} png:-")
104
+ expect(Riiif::CommandRunner).to receive(:execute).with("convert -resize 12.5% -strip #{filename} png:-")
103
105
  subject.render(size: 'pct:12.5', format: 'png')
104
106
  end
105
107
  it 'handles w,' do
106
- expect(Riiif::CommandRunner).to receive(:execute).with("convert -resize 50 #{filename} png:-")
108
+ expect(Riiif::CommandRunner).to receive(:execute).with("convert -resize 50 -strip #{filename} png:-")
107
109
  subject.render(size: '50,', format: 'png')
108
110
  end
109
111
  it 'handles ,h' do
110
- expect(Riiif::CommandRunner).to receive(:execute).with("convert -resize x50 #{filename} png:-")
112
+ expect(Riiif::CommandRunner).to receive(:execute).with("convert -resize x50 -strip #{filename} png:-")
111
113
  subject.render(size: ',50', format: 'png')
112
114
  end
113
115
  it 'handles w,h' do
114
- expect(Riiif::CommandRunner).to receive(:execute).with("convert -resize 150x75! #{filename} png:-")
116
+ expect(Riiif::CommandRunner).to receive(:execute).with("convert -resize 150x75! -strip #{filename} png:-")
115
117
  subject.render(size: '150,75', format: 'png')
116
118
  end
117
119
  it 'handles bestfit (!w,h)' do
118
- expect(Riiif::CommandRunner).to receive(:execute).with("convert -resize 150x75 #{filename} png:-")
120
+ expect(Riiif::CommandRunner).to receive(:execute).with("convert -resize 150x75 -strip #{filename} png:-")
119
121
  subject.render(size: '!150,75', format: 'png')
120
122
  end
121
123
  it 'raises an error for invalid size' do
@@ -125,12 +127,12 @@ RSpec.describe Riiif::Image do
125
127
 
126
128
  describe 'rotate' do
127
129
  it 'returns the original when specifing full size' do
128
- expect(Riiif::CommandRunner).to receive(:execute).with("convert #{filename} png:-")
130
+ expect(Riiif::CommandRunner).to receive(:execute).with("convert -strip #{filename} png:-")
129
131
  subject.render(rotation: '0', format: 'png')
130
132
  end
131
133
  it 'handles floats' do
132
134
  expect(Riiif::CommandRunner).to receive(:execute)
133
- .with("convert -virtual-pixel white +distort srt 22.5 #{filename} png:-")
135
+ .with("convert -virtual-pixel white +distort srt 22.5 -strip #{filename} png:-")
134
136
  subject.render(rotation: '22.5', format: 'png')
135
137
  end
136
138
  it 'raises an error for invalid angle' do
@@ -140,20 +142,20 @@ RSpec.describe Riiif::Image do
140
142
 
141
143
  describe 'quality' do
142
144
  it 'returns the original when specifing default' do
143
- expect(Riiif::CommandRunner).to receive(:execute).with("convert #{filename} png:-")
145
+ expect(Riiif::CommandRunner).to receive(:execute).with("convert -strip #{filename} png:-")
144
146
  subject.render(quality: 'default', format: 'png')
145
147
  end
146
148
  it 'returns the original when specifing color' do
147
- expect(Riiif::CommandRunner).to receive(:execute).with("convert #{filename} png:-")
149
+ expect(Riiif::CommandRunner).to receive(:execute).with("convert -strip #{filename} png:-")
148
150
  subject.render(quality: 'color', format: 'png')
149
151
  end
150
152
  it 'converts to grayscale' do
151
- expect(Riiif::CommandRunner).to receive(:execute).with("convert -colorspace Gray #{filename} png:-")
153
+ expect(Riiif::CommandRunner).to receive(:execute).with("convert -colorspace Gray -strip #{filename} png:-")
152
154
  subject.render(quality: 'grey', format: 'png')
153
155
  end
154
156
  it 'converts to bitonal' do
155
157
  expect(Riiif::CommandRunner).to receive(:execute)
156
- .with("convert -colorspace Gray -type Bilevel #{filename} png:-")
158
+ .with("convert -colorspace Gray -type Bilevel -strip #{filename} png:-")
157
159
  subject.render(quality: 'bitonal', format: 'png')
158
160
  end
159
161
  it 'raises an error for invalid angle' do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: riiif
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.0
4
+ version: 1.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Justin Coyne
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-04-10 00:00:00.000000000 Z
11
+ date: 2017-04-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: railties