riiif 1.3.0 → 1.4.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.
- checksums.yaml +4 -4
- data/app/services/riiif/command_runner.rb +1 -1
- data/app/services/riiif/imagemagick_command_factory.rb +60 -22
- data/lib/riiif/version.rb +1 -1
- data/lib/riiif.rb +2 -1
- data/spec/models/riiif/image_spec.rb +20 -18
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0aaf0ae50831c1b402852fee520e6a4a0c9b8760
|
4
|
+
data.tar.gz: 141b672ec9ce926ae80d139febb926a82d607cc2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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,
|
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
|
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 &&
|
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
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)
|
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.
|
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-
|
11
|
+
date: 2017-04-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: railties
|