riiif 2.1.0 → 2.8.1
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/.github/dependabot.yml +6 -0
- data/.github/workflows/ruby.yml +39 -0
- data/.rubocop_todo.yml +115 -16
- data/Gemfile +2 -12
- data/README.md +29 -9
- data/app/controllers/riiif/images_controller.rb +1 -1
- data/app/extractors/riiif/abstract_info_extractor.rb +12 -0
- data/app/{services → extractors}/riiif/image_magick_info_extractor.rb +2 -7
- data/app/extractors/riiif/vips_info_extractor.rb +22 -0
- data/app/models/riiif/file.rb +11 -24
- data/app/models/riiif/image.rb +0 -3
- data/app/resolvers/riiif/abstract_file_system_resolver.rb +1 -11
- data/app/resolvers/riiif/akubra_system_file_resolver.rb +1 -0
- data/app/resolvers/riiif/file_system_file_resolver.rb +1 -1
- data/app/resolvers/riiif/http_file_resolver.rb +11 -3
- data/app/services/riiif/crop.rb +40 -0
- data/app/services/riiif/imagemagick_command_factory.rb +1 -1
- data/app/services/riiif/vips_resize.rb +47 -0
- data/app/transformers/riiif/vips_transformer.rb +103 -0
- data/docs/vips_comparison.md +257 -0
- data/lib/riiif/engine.rb +14 -0
- data/lib/riiif/version.rb +1 -1
- data/lib/riiif.rb +14 -0
- data/riiif.gemspec +9 -7
- data/spec/controllers/riiif/images_controller_spec.rb +8 -8
- data/spec/extractors/riiif/image_magick_info_extractor_spec.rb +31 -0
- data/spec/extractors/riiif/vips_info_extractor_spec.rb +76 -0
- data/spec/fixtures/test.jpg +0 -0
- data/spec/fixtures/test.png +0 -0
- data/spec/fixtures/test.tif +0 -0
- data/spec/models/riiif/file_spec.rb +35 -0
- data/spec/models/riiif/file_system_file_resolver_spec.rb +7 -0
- data/spec/models/riiif/http_file_resolver_spec.rb +1 -1
- data/spec/models/riiif/image_spec.rb +27 -21
- data/spec/spec_helper.rb +0 -6
- data/spec/test_app_templates/lib/generators/test_app_generator.rb +6 -1
- data/spec/transformers/riiif/kakadu_transformer_spec.rb +8 -8
- data/spec/transformers/riiif/vips_transformer_spec.rb +271 -0
- metadata +49 -19
- data/.travis.yml +0 -11
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 5c83cf037ced763741c5aa704db17564fd43ee2610866d27629b1de4700c518a
|
|
4
|
+
data.tar.gz: 447135b1b851c29969cd42a91a51b26facb1084b47dc246422b11a15de0dcbc5
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 86952c0517dfd44217aee70ae4927209aaa7c4078c9142126a6f0a06fe831774371dffb0191c2719cb868249b98b324cbfbf7853c2518622bb67dc2d1afab182
|
|
7
|
+
data.tar.gz: f315b4762cf831614a80728ac072678ea4ad9f1fc38cbc836cd7f6e3eaf6c2009b870682e0024d4cebca02c9da919a33dde3b66bcd98ac8da5f2f4d5691b23fd
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# This workflow uses actions that are not certified by GitHub.
|
|
2
|
+
# They are provided by a third-party and are governed by
|
|
3
|
+
# separate terms of service, privacy policy, and support
|
|
4
|
+
# documentation.
|
|
5
|
+
# This workflow will download a prebuilt Ruby version, install dependencies and run tests with Rake
|
|
6
|
+
# For more information see: https://github.com/marketplace/actions/setup-ruby-jruby-and-truffleruby
|
|
7
|
+
|
|
8
|
+
name: CI
|
|
9
|
+
|
|
10
|
+
on:
|
|
11
|
+
push:
|
|
12
|
+
branches:
|
|
13
|
+
- master
|
|
14
|
+
pull_request:
|
|
15
|
+
|
|
16
|
+
jobs:
|
|
17
|
+
test:
|
|
18
|
+
runs-on: ubuntu-latest
|
|
19
|
+
strategy:
|
|
20
|
+
matrix:
|
|
21
|
+
ruby: ["3.2", "3.3", "3.4"]
|
|
22
|
+
rails: ["8.1.1", "8.0.4", "7.2.3"]
|
|
23
|
+
steps:
|
|
24
|
+
- name: Install ImageMagick
|
|
25
|
+
run: sudo apt install imagemagick
|
|
26
|
+
- uses: actions/checkout@v6
|
|
27
|
+
- name: Set up Ruby
|
|
28
|
+
uses: ruby/setup-ruby@v1
|
|
29
|
+
with:
|
|
30
|
+
ruby-version: ${{ matrix.ruby }}
|
|
31
|
+
- name: Install dependencies
|
|
32
|
+
run: bundle install
|
|
33
|
+
env:
|
|
34
|
+
RAILS_VERSION: ${{ matrix.rails }}
|
|
35
|
+
- name: Run tests
|
|
36
|
+
run: bundle exec rake
|
|
37
|
+
env:
|
|
38
|
+
RAILS_VERSION: ${{ matrix.rails }}
|
|
39
|
+
ENGINE_CART_RAILS_OPTIONS: "--skip-git --skip-listen --skip-spring --skip-keeps --skip-action-cable --skip-coffee --skip-test"
|
data/.rubocop_todo.yml
CHANGED
|
@@ -1,16 +1,54 @@
|
|
|
1
1
|
# This configuration was generated by
|
|
2
2
|
# `rubocop --auto-gen-config`
|
|
3
|
-
# on
|
|
3
|
+
# on 2022-02-28 10:01:41 -0800 using RuboCop version 0.85.1.
|
|
4
4
|
# The point is for the user to remove these configuration records
|
|
5
5
|
# one by one as the offenses are removed from the code base.
|
|
6
6
|
# Note that changes in the inspected code, or installation of new
|
|
7
7
|
# versions of RuboCop, may require this file to be generated again.
|
|
8
8
|
|
|
9
|
-
# Offense count:
|
|
9
|
+
# Offense count: 6
|
|
10
|
+
# Cop supports --auto-correct.
|
|
11
|
+
# Configuration parameters: AllowMultipleStyles, EnforcedHashRocketStyle, EnforcedColonStyle, EnforcedLastArgumentHashStyle.
|
|
12
|
+
# SupportedHashRocketStyles: key, separator, table
|
|
13
|
+
# SupportedColonStyles: key, separator, table
|
|
14
|
+
# SupportedLastArgumentHashStyles: always_inspect, always_ignore, ignore_implicit, ignore_explicit
|
|
15
|
+
Layout/HashAlignment:
|
|
16
|
+
Exclude:
|
|
17
|
+
- 'spec/controllers/riiif/images_controller_spec.rb'
|
|
18
|
+
|
|
19
|
+
# Offense count: 62
|
|
20
|
+
# Cop supports --auto-correct.
|
|
21
|
+
# Configuration parameters: EnforcedStyle.
|
|
22
|
+
# SupportedStyles: normal, indented_internal_methods
|
|
23
|
+
Layout/IndentationConsistency:
|
|
24
|
+
Exclude:
|
|
25
|
+
- 'app/controllers/riiif/images_controller.rb'
|
|
26
|
+
- 'app/resolvers/riiif/file_system_file_resolver.rb'
|
|
27
|
+
- 'app/resolvers/riiif/http_file_resolver.rb'
|
|
28
|
+
- 'app/services/riiif/crop.rb'
|
|
29
|
+
- 'app/services/riiif/imagemagick_command_factory.rb'
|
|
30
|
+
- 'app/services/riiif/kakadu_command_factory.rb'
|
|
31
|
+
- 'app/services/riiif/resize.rb'
|
|
32
|
+
- 'app/transformers/riiif/kakadu_transformer.rb'
|
|
33
|
+
|
|
34
|
+
# Offense count: 62
|
|
35
|
+
# Cop supports --auto-correct.
|
|
36
|
+
# Configuration parameters: Width, IgnoredPatterns.
|
|
37
|
+
Layout/IndentationWidth:
|
|
38
|
+
Exclude:
|
|
39
|
+
- 'app/controllers/riiif/images_controller.rb'
|
|
40
|
+
- 'app/resolvers/riiif/file_system_file_resolver.rb'
|
|
41
|
+
- 'app/resolvers/riiif/http_file_resolver.rb'
|
|
42
|
+
- 'app/services/riiif/crop.rb'
|
|
43
|
+
- 'app/services/riiif/imagemagick_command_factory.rb'
|
|
44
|
+
- 'app/services/riiif/kakadu_command_factory.rb'
|
|
45
|
+
- 'app/services/riiif/resize.rb'
|
|
46
|
+
- 'app/transformers/riiif/kakadu_transformer.rb'
|
|
47
|
+
|
|
48
|
+
# Offense count: 1
|
|
10
49
|
# Configuration parameters: AllowSafeAssignment.
|
|
11
50
|
Lint/AssignmentInCondition:
|
|
12
51
|
Exclude:
|
|
13
|
-
- 'app/models/riiif/file.rb'
|
|
14
52
|
- 'app/resolvers/riiif/http_file_resolver.rb'
|
|
15
53
|
|
|
16
54
|
# Offense count: 1
|
|
@@ -18,27 +56,32 @@ Lint/DuplicateMethods:
|
|
|
18
56
|
Exclude:
|
|
19
57
|
- 'app/resolvers/riiif/http_file_resolver.rb'
|
|
20
58
|
|
|
21
|
-
# Offense count:
|
|
22
|
-
|
|
59
|
+
# Offense count: 2
|
|
60
|
+
# Configuration parameters: AllowComments.
|
|
61
|
+
Lint/SuppressedException:
|
|
23
62
|
Exclude:
|
|
63
|
+
- 'app/controllers/riiif/images_controller.rb'
|
|
24
64
|
- 'spec/models/riiif/http_file_resolver_spec.rb'
|
|
25
65
|
|
|
26
|
-
# Offense count: 1
|
|
27
|
-
Lint/UselessAssignment:
|
|
28
|
-
Exclude:
|
|
29
|
-
- 'app/models/riiif/file.rb'
|
|
30
|
-
|
|
31
66
|
# Offense count: 21
|
|
32
67
|
# Configuration parameters: CountComments, ExcludedMethods.
|
|
68
|
+
# ExcludedMethods: refine
|
|
33
69
|
Metrics/BlockLength:
|
|
34
|
-
Max:
|
|
70
|
+
Max: 237
|
|
35
71
|
|
|
36
|
-
# Offense count:
|
|
72
|
+
# Offense count: 2
|
|
73
|
+
Metrics/ClassLength:
|
|
74
|
+
Exclude:
|
|
75
|
+
- 'app/services/riiif/crop.rb'
|
|
76
|
+
- 'app/services/riiif/resize.rb'
|
|
77
|
+
|
|
78
|
+
# Offense count: 1
|
|
79
|
+
# Configuration parameters: IgnoredMethods.
|
|
37
80
|
Metrics/CyclomaticComplexity:
|
|
38
81
|
Max: 7
|
|
39
82
|
|
|
40
83
|
# Offense count: 3
|
|
41
|
-
# Configuration parameters: CountComments.
|
|
84
|
+
# Configuration parameters: CountComments, ExcludedMethods.
|
|
42
85
|
Metrics/MethodLength:
|
|
43
86
|
Max: 18
|
|
44
87
|
|
|
@@ -47,12 +90,20 @@ Metrics/MethodLength:
|
|
|
47
90
|
Metrics/ParameterLists:
|
|
48
91
|
Max: 6
|
|
49
92
|
|
|
93
|
+
# Offense count: 3
|
|
94
|
+
# Cop supports --auto-correct.
|
|
95
|
+
Performance/RegexpMatch:
|
|
96
|
+
Exclude:
|
|
97
|
+
- 'app/resolvers/riiif/file_system_file_resolver.rb'
|
|
98
|
+
- 'app/services/riiif/imagemagick_command_factory.rb'
|
|
99
|
+
|
|
50
100
|
# Offense count: 1
|
|
51
101
|
RSpec/DescribeClass:
|
|
52
102
|
Exclude:
|
|
53
103
|
- 'spec/routing/resize_routes_spec.rb'
|
|
54
104
|
|
|
55
105
|
# Offense count: 2
|
|
106
|
+
# Cop supports --auto-correct.
|
|
56
107
|
# Configuration parameters: SkipBlocks, EnforcedStyle.
|
|
57
108
|
# SupportedStyles: described_class, explicit
|
|
58
109
|
RSpec/DescribedClass:
|
|
@@ -67,9 +118,11 @@ RSpec/ExampleLength:
|
|
|
67
118
|
- 'spec/models/riiif/http_file_resolver_spec.rb'
|
|
68
119
|
- 'spec/transformers/riiif/kakadu_transformer_spec.rb'
|
|
69
120
|
|
|
70
|
-
# Offense count:
|
|
121
|
+
# Offense count: 2
|
|
122
|
+
# Cop supports --auto-correct.
|
|
71
123
|
RSpec/LeadingSubject:
|
|
72
124
|
Exclude:
|
|
125
|
+
- 'spec/controllers/riiif/images_controller_spec.rb'
|
|
73
126
|
- 'spec/transformers/riiif/kakadu_transformer_spec.rb'
|
|
74
127
|
|
|
75
128
|
# Offense count: 43
|
|
@@ -78,7 +131,8 @@ RSpec/LeadingSubject:
|
|
|
78
131
|
RSpec/MessageSpies:
|
|
79
132
|
EnforcedStyle: receive
|
|
80
133
|
|
|
81
|
-
# Offense count:
|
|
134
|
+
# Offense count: 24
|
|
135
|
+
# Configuration parameters: IgnoreSharedExamples.
|
|
82
136
|
RSpec/NamedSubject:
|
|
83
137
|
Exclude:
|
|
84
138
|
- 'spec/controllers/riiif/images_controller_spec.rb'
|
|
@@ -93,18 +147,51 @@ RSpec/RepeatedExample:
|
|
|
93
147
|
- 'spec/controllers/riiif/images_controller_spec.rb'
|
|
94
148
|
|
|
95
149
|
# Offense count: 7
|
|
96
|
-
# Configuration parameters: IgnoreSymbolicNames.
|
|
150
|
+
# Configuration parameters: IgnoreNameless, IgnoreSymbolicNames.
|
|
97
151
|
RSpec/VerifiedDoubles:
|
|
98
152
|
Exclude:
|
|
99
153
|
- 'spec/controllers/riiif/images_controller_spec.rb'
|
|
100
154
|
- 'spec/services/riiif/imagemagick_command_factory_spec.rb'
|
|
101
155
|
- 'spec/services/riiif/kakadu_command_factory_spec.rb'
|
|
102
156
|
|
|
157
|
+
# Offense count: 2
|
|
158
|
+
# Cop supports --auto-correct.
|
|
159
|
+
# Configuration parameters: NilOrEmpty, NotPresent, UnlessPresent.
|
|
160
|
+
Rails/Blank:
|
|
161
|
+
Exclude:
|
|
162
|
+
- 'spec/controllers/riiif/images_controller_spec.rb'
|
|
163
|
+
|
|
103
164
|
# Offense count: 1
|
|
165
|
+
# Configuration parameters: EnforcedStyle.
|
|
166
|
+
# SupportedStyles: slashes, arguments
|
|
104
167
|
Rails/FilePath:
|
|
105
168
|
Exclude:
|
|
106
169
|
- 'spec/models/riiif/akubra_system_file_resolver_spec.rb'
|
|
107
170
|
|
|
171
|
+
# Offense count: 37
|
|
172
|
+
# Cop supports --auto-correct.
|
|
173
|
+
# Configuration parameters: EnforcedStyle.
|
|
174
|
+
# SupportedStyles: always, always_true, never
|
|
175
|
+
Style/FrozenStringLiteralComment:
|
|
176
|
+
Enabled: false
|
|
177
|
+
|
|
178
|
+
# Offense count: 2
|
|
179
|
+
# Cop supports --auto-correct.
|
|
180
|
+
# Configuration parameters: EnforcedStyle.
|
|
181
|
+
# SupportedStyles: literals, strict
|
|
182
|
+
Style/MutableConstant:
|
|
183
|
+
Exclude:
|
|
184
|
+
- 'lib/riiif/routes.rb'
|
|
185
|
+
|
|
186
|
+
# Offense count: 1
|
|
187
|
+
# Cop supports --auto-correct.
|
|
188
|
+
# Configuration parameters: AutoCorrect, EnforcedStyle, IgnoredMethods.
|
|
189
|
+
# SupportedStyles: predicate, comparison
|
|
190
|
+
Style/NumericPredicate:
|
|
191
|
+
Exclude:
|
|
192
|
+
- 'spec/**/*'
|
|
193
|
+
- 'app/services/riiif/imagemagick_command_factory.rb'
|
|
194
|
+
|
|
108
195
|
# Offense count: 4
|
|
109
196
|
# Cop supports --auto-correct.
|
|
110
197
|
# Configuration parameters: PreferredDelimiters.
|
|
@@ -114,3 +201,15 @@ Style/PercentLiteralDelimiters:
|
|
|
114
201
|
- 'app/resolvers/riiif/file_system_file_resolver.rb'
|
|
115
202
|
- 'spec/controllers/riiif/images_controller_spec.rb'
|
|
116
203
|
- 'spec/models/riiif/http_file_resolver_spec.rb'
|
|
204
|
+
|
|
205
|
+
# Offense count: 1
|
|
206
|
+
# Cop supports --auto-correct.
|
|
207
|
+
Style/RedundantBegin:
|
|
208
|
+
Exclude:
|
|
209
|
+
- 'app/resolvers/riiif/http_file_resolver.rb'
|
|
210
|
+
|
|
211
|
+
# Offense count: 1
|
|
212
|
+
# Cop supports --auto-correct.
|
|
213
|
+
Style/RedundantFreeze:
|
|
214
|
+
Exclude:
|
|
215
|
+
- 'app/services/riiif/imagemagick_command_factory.rb'
|
data/Gemfile
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
source 'https://rubygems.org'
|
|
2
2
|
|
|
3
|
-
gem 'byebug'
|
|
4
3
|
# Specify your gem's dependencies in riiif.gemspec
|
|
5
4
|
gemspec
|
|
6
5
|
|
|
7
6
|
# BEGIN ENGINE_CART BLOCK
|
|
8
|
-
# engine_cart: 2.0
|
|
9
|
-
# engine_cart stanza:
|
|
7
|
+
# engine_cart: 2.6.0
|
|
8
|
+
# engine_cart stanza: 2.5.0
|
|
10
9
|
# the below comes from engine_cart, a gem used to test this Rails engine gem in the context of a Rails app.
|
|
11
10
|
file = File.expand_path('Gemfile', ENV['ENGINE_CART_DESTINATION'] || ENV['RAILS_ROOT'] || File.expand_path('.internal_test_app', File.dirname(__FILE__)))
|
|
12
11
|
if File.exist?(file)
|
|
@@ -27,14 +26,5 @@ else
|
|
|
27
26
|
gem 'rails', ENV['RAILS_VERSION']
|
|
28
27
|
end
|
|
29
28
|
end
|
|
30
|
-
|
|
31
|
-
case ENV['RAILS_VERSION']
|
|
32
|
-
when /^4.2/
|
|
33
|
-
gem 'responders', '~> 2.0'
|
|
34
|
-
gem 'sass-rails', '>= 5.0'
|
|
35
|
-
gem 'coffee-rails', '~> 4.1.0'
|
|
36
|
-
when /^4.[01]/
|
|
37
|
-
gem 'sass-rails', '< 5.0'
|
|
38
|
-
end
|
|
39
29
|
end
|
|
40
30
|
# END ENGINE_CART BLOCK
|
data/README.md
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
# Riiif
|
|
2
2
|
[](http://badge.fury.io/rb/riiif)
|
|
3
|
-
[](https://coveralls.io/github/curationexperts/riiif?branch=master)
|
|
4
3
|
|
|
5
|
-
|
|
6
|
-
A Ruby IIIF image server as a rails engine
|
|
4
|
+
A Ruby IIIF image server as a rails engine.
|
|
7
5
|
|
|
8
6
|
## Installation
|
|
9
7
|
|
|
10
|
-
RIIIF
|
|
8
|
+
To use RIIIF, you need to install at least one of Imagemagick, Graphicsmagick, or Vips (libvips) (see [comparison](docs/vips_comparison.md)). By default, RIIIF will use Imagemagick.
|
|
9
|
+
|
|
10
|
+
To install Imagemagick on a Mac using Homebrew you can follow these instructions:
|
|
11
11
|
|
|
12
12
|
ImageMagick (7.0.4) may be installed with a few options:
|
|
13
13
|
* `--with-ghostscript` Compile with Ghostscript for Postscript/PDF support
|
|
@@ -33,6 +33,16 @@ Or install it yourself as:
|
|
|
33
33
|
|
|
34
34
|
## Configure
|
|
35
35
|
|
|
36
|
+
Any of the following code examples should be included in a `config/initializers/riiif.rb` file in your application (or somewhere else loaded in your app environment) like so:
|
|
37
|
+
|
|
38
|
+
```ruby
|
|
39
|
+
Rails.application.config.to_prepare do
|
|
40
|
+
# code goes here
|
|
41
|
+
end
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
For test applications generated by engine cart (see [Running the tests](#running-the-tests)), this would be `<cloned repo folder>/.internal_test_app/config/initializers/riiif.rb`.
|
|
45
|
+
|
|
36
46
|
### Images on the servers file system.
|
|
37
47
|
|
|
38
48
|
By default Riiif is set to load images from the filesystem using the Riiif::FileSystemFileResolver.
|
|
@@ -48,7 +58,7 @@ When the Id passed in is "foo_image", then it will look for an image file using
|
|
|
48
58
|
### Images retrieved over HTTP
|
|
49
59
|
It's preferable to use files on the filesystem, because this avoids the overhead of downloading the file. If this is unavoidable, Riiif can be configured to fetch files from the network. To enable this behavior, configure Riiif to use an alternative resolver:
|
|
50
60
|
```
|
|
51
|
-
Riiif::Image.file_resolver = Riiif::
|
|
61
|
+
Riiif::Image.file_resolver = Riiif::HttpFileResolver.new
|
|
52
62
|
```
|
|
53
63
|
Then we configure the resolver with a mechanism for mapping the provided id to a url:
|
|
54
64
|
```
|
|
@@ -77,15 +87,25 @@ See [benchmark](docs/benchmark.md) for details
|
|
|
77
87
|
|
|
78
88
|
To use [GraphicsMagick](http://www.graphicsmagick.org/) instead of ImageMagick
|
|
79
89
|
|
|
80
|
-
|
|
81
|
-
|
|
90
|
+
```ruby
|
|
91
|
+
Riiif::ImagemagickCommandFactory.external_command = "gm convert"
|
|
92
|
+
Riiif::ImageMagickInfoExtractor.external_command = "gm identify"
|
|
93
|
+
```
|
|
82
94
|
|
|
83
95
|
You will of course need to install GraphicsMagick on your system.
|
|
84
96
|
|
|
97
|
+
### Libvips (aka Vips)
|
|
98
|
+
|
|
99
|
+
To use [libvips](https://www.libvips.org/) instead of ImageMagick
|
|
100
|
+
|
|
101
|
+
```ruby
|
|
102
|
+
Riiif::Engine.config.use_vips = true
|
|
103
|
+
```
|
|
104
|
+
|
|
85
105
|
## Usage
|
|
86
106
|
|
|
87
107
|
Add the routes to your application by inserting the following line into `config/routes.rb`
|
|
88
|
-
```
|
|
108
|
+
```ruby
|
|
89
109
|
mount Riiif::Engine => '/image-service', as: 'riiif'
|
|
90
110
|
```
|
|
91
111
|
|
|
@@ -154,7 +174,7 @@ Create an initializer like this in `config/initializers/riiif_initializer.rb`
|
|
|
154
174
|
|
|
155
175
|
```ruby
|
|
156
176
|
# Tell RIIIF to get files via HTTP (not from the local disk)
|
|
157
|
-
Riiif::Image.file_resolver = Riiif::
|
|
177
|
+
Riiif::Image.file_resolver = Riiif::HttpFileResolver.new
|
|
158
178
|
|
|
159
179
|
# This tells RIIIF how to resolve the identifier to a URI in Fedora
|
|
160
180
|
Riiif::Image.file_resolver.id_to_uri = lambda do |id|
|
|
@@ -1,17 +1,12 @@
|
|
|
1
1
|
module Riiif
|
|
2
2
|
# Get information using imagemagick to interrogate the file
|
|
3
|
-
class ImageMagickInfoExtractor
|
|
3
|
+
class ImageMagickInfoExtractor < AbstractInfoExtractor
|
|
4
4
|
# perhaps you want to use GraphicsMagick instead, set to "gm identify"
|
|
5
|
-
class_attribute :external_command
|
|
6
5
|
self.external_command = 'identify'
|
|
7
6
|
|
|
8
|
-
def initialize(path)
|
|
9
|
-
@path = path
|
|
10
|
-
end
|
|
11
|
-
|
|
12
7
|
def extract
|
|
13
8
|
height, width, format, channels = Riiif::CommandRunner.execute(
|
|
14
|
-
"#{external_command} -format '%h %w %m %[channels]' #{@path}[0]"
|
|
9
|
+
"#{external_command} -format '%h %w %m %[channels]' '#{@path}[0]'"
|
|
15
10
|
).split(' ')
|
|
16
11
|
|
|
17
12
|
{
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
require 'ruby-vips' if Riiif::Engine.config.use_vips
|
|
2
|
+
|
|
3
|
+
module Riiif
|
|
4
|
+
# Get information using (lib)vips to interrogate the file
|
|
5
|
+
class VipsInfoExtractor < AbstractInfoExtractor
|
|
6
|
+
self.external_command = 'vipsheader'
|
|
7
|
+
|
|
8
|
+
def extract
|
|
9
|
+
attributes = Riiif::CommandRunner.execute("#{external_command} '#{@path}' -a")
|
|
10
|
+
.split(/\n/)
|
|
11
|
+
.map { |str| str.strip.split(': ', 2) }.to_h
|
|
12
|
+
width, height = attributes.values_at("width", "height")
|
|
13
|
+
|
|
14
|
+
{
|
|
15
|
+
height: Integer(height),
|
|
16
|
+
width: Integer(width),
|
|
17
|
+
format: attributes["vips-loader"].match?("pngload") ? "PNG" : "JPEG",
|
|
18
|
+
channels: ::Vips::Image.new_from_file(@path.to_s).has_alpha? ? "srgba" : "srgb"
|
|
19
|
+
}
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
data/app/models/riiif/file.rb
CHANGED
|
@@ -4,7 +4,14 @@ module Riiif
|
|
|
4
4
|
|
|
5
5
|
class_attribute :info_extractor_class
|
|
6
6
|
# TODO: add alternative that uses kdu_jp2info
|
|
7
|
-
|
|
7
|
+
|
|
8
|
+
def self.info_extractor_class
|
|
9
|
+
if Riiif.use_vips?
|
|
10
|
+
VipsInfoExtractor
|
|
11
|
+
else
|
|
12
|
+
ImageMagickInfoExtractor
|
|
13
|
+
end
|
|
14
|
+
end
|
|
8
15
|
|
|
9
16
|
# @param input_path [String] The location of an image file
|
|
10
17
|
def initialize(input_path, tempfile = nil)
|
|
@@ -12,28 +19,6 @@ module Riiif
|
|
|
12
19
|
@tempfile = tempfile # ensures that the tempfile will stick around until this file is garbage collected.
|
|
13
20
|
end
|
|
14
21
|
|
|
15
|
-
def self.read(stream, ext)
|
|
16
|
-
create(ext) do |f|
|
|
17
|
-
while chunk = stream.read(8192)
|
|
18
|
-
f.write(chunk)
|
|
19
|
-
end
|
|
20
|
-
end
|
|
21
|
-
end
|
|
22
|
-
deprecation_deprecate read: 'Riiif::File.read is deprecated and will be removed in version 2.0'
|
|
23
|
-
|
|
24
|
-
# Yields a tempfile to the provided block
|
|
25
|
-
# @return [Riiif::File] a file backed by the Tempfile
|
|
26
|
-
def self.create(ext = nil, _validate = true, &block)
|
|
27
|
-
tempfile = Tempfile.new(['mini_magick', ext.to_s.downcase])
|
|
28
|
-
tempfile.binmode
|
|
29
|
-
block.call(tempfile)
|
|
30
|
-
tempfile.close
|
|
31
|
-
image = new(tempfile.path, tempfile)
|
|
32
|
-
ensure
|
|
33
|
-
tempfile.close if tempfile
|
|
34
|
-
end
|
|
35
|
-
deprecation_deprecate create: 'Riiif::File.create is deprecated and will be removed in version 2.0'
|
|
36
|
-
|
|
37
22
|
# @param [Transformation] transformation
|
|
38
23
|
# @param [ImageInformation] image_info
|
|
39
24
|
# @return [String] the processed image data
|
|
@@ -42,7 +27,9 @@ module Riiif
|
|
|
42
27
|
end
|
|
43
28
|
|
|
44
29
|
def transformer
|
|
45
|
-
if Riiif.
|
|
30
|
+
if Riiif.use_vips?
|
|
31
|
+
VipsTransformer
|
|
32
|
+
elsif Riiif.kakadu_enabled? && path.ends_with?('.jp2')
|
|
46
33
|
KakaduTransformer
|
|
47
34
|
else
|
|
48
35
|
ImagemagickTransformer
|
data/app/models/riiif/image.rb
CHANGED
|
@@ -33,9 +33,6 @@ module Riiif
|
|
|
33
33
|
@file ||= file_resolver.find(id)
|
|
34
34
|
end
|
|
35
35
|
|
|
36
|
-
alias image file
|
|
37
|
-
deprecation_deprecate image: 'Use Image#file instead. This will be removed in riiif 2.0'
|
|
38
|
-
|
|
39
36
|
##
|
|
40
37
|
# @param [ActiveSupport::HashWithIndifferentAccess] args
|
|
41
38
|
# @return [String] the image data
|
|
@@ -4,19 +4,9 @@ module Riiif
|
|
|
4
4
|
attr_accessor :base_path
|
|
5
5
|
|
|
6
6
|
def initialize(base_path: nil)
|
|
7
|
-
@base_path = base_path
|
|
7
|
+
@base_path = base_path
|
|
8
8
|
end
|
|
9
9
|
|
|
10
|
-
def default_base_path
|
|
11
|
-
Deprecation.warn(self, 'Initializing a file resolver without setting the base path ' \
|
|
12
|
-
'is deprecated and will be removed in Riiif 2.0', caller(2))
|
|
13
|
-
@root ||= ::File.expand_path(::File.join(::File.dirname(__FILE__), '../..'))
|
|
14
|
-
::File.join(@root, 'spec/samples')
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
attr_reader :root
|
|
18
|
-
deprecation_deprecate :root
|
|
19
|
-
|
|
20
10
|
def find(id)
|
|
21
11
|
Riiif::File.new(path(id))
|
|
22
12
|
end
|
|
@@ -14,7 +14,7 @@ module Riiif
|
|
|
14
14
|
|
|
15
15
|
# @return [Boolean] true if the id matches the regex
|
|
16
16
|
def validate_identifier(id:, regex: identifier_regex)
|
|
17
|
-
return true if id =~ regex
|
|
17
|
+
return true if id.to_s =~ regex
|
|
18
18
|
Rails.logger.warn "Invalid characters in id `#{id}`"
|
|
19
19
|
false
|
|
20
20
|
end
|
|
@@ -2,11 +2,11 @@ require 'open-uri'
|
|
|
2
2
|
require 'active_support/core_ext/file/atomic'
|
|
3
3
|
|
|
4
4
|
module Riiif
|
|
5
|
-
class
|
|
5
|
+
class HttpFileResolver
|
|
6
6
|
# Set a lambda that maps the first parameter (id) to a URL
|
|
7
7
|
# Example:
|
|
8
8
|
#
|
|
9
|
-
# resolver = Riiif::
|
|
9
|
+
# resolver = Riiif::HttpFileResolver.new
|
|
10
10
|
# resolver.id_to_uri = lambda do |id|
|
|
11
11
|
# "http://upload.wikimedia.org/wikipedia/commons/thumb/a/a4/#{id}.jpg/600px-#{id}.jpg"
|
|
12
12
|
# end
|
|
@@ -63,7 +63,7 @@ module Riiif
|
|
|
63
63
|
benchmark("Riiif downloaded #{url}") do
|
|
64
64
|
::File.atomic_write(file_name, cache_path) do |local|
|
|
65
65
|
begin
|
|
66
|
-
|
|
66
|
+
handler.open(url, **download_opts) do |remote|
|
|
67
67
|
while chunk = remote.read(8192)
|
|
68
68
|
local.write(chunk)
|
|
69
69
|
end
|
|
@@ -85,6 +85,14 @@ module Riiif
|
|
|
85
85
|
def ensure_cache_path(path)
|
|
86
86
|
FileUtils.makedirs(path) unless ::File.exist?(path)
|
|
87
87
|
end
|
|
88
|
+
|
|
89
|
+
def handler
|
|
90
|
+
if url.match?(URI.regexp)
|
|
91
|
+
URI
|
|
92
|
+
else
|
|
93
|
+
Kernel
|
|
94
|
+
end
|
|
95
|
+
end
|
|
88
96
|
end
|
|
89
97
|
|
|
90
98
|
protected
|
data/app/services/riiif/crop.rb
CHANGED
|
@@ -45,8 +45,35 @@ module Riiif
|
|
|
45
45
|
end
|
|
46
46
|
end
|
|
47
47
|
|
|
48
|
+
def to_vips
|
|
49
|
+
case region
|
|
50
|
+
when IIIF::Image::Region::Full
|
|
51
|
+
nil
|
|
52
|
+
when IIIF::Image::Region::Absolute
|
|
53
|
+
[region.offset_x, region.offset_y, region.width, region.height]
|
|
54
|
+
when IIIF::Image::Region::Square
|
|
55
|
+
vips_square
|
|
56
|
+
when IIIF::Image::Region::Percent
|
|
57
|
+
vips_percent
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
48
61
|
private
|
|
49
62
|
|
|
63
|
+
def vips_percent
|
|
64
|
+
# Calculate x values
|
|
65
|
+
offset_x, width = [region.x_pct, region.width_pct].map do |percent|
|
|
66
|
+
(image_info.width * percentage_to_fraction(percent)).round
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# Calculate y values
|
|
70
|
+
offset_y, height = [region.y_pct, region.height_pct].map do |percent|
|
|
71
|
+
(image_info.height * percentage_to_fraction(percent)).round
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
[offset_x, offset_y, width, height]
|
|
75
|
+
end
|
|
76
|
+
|
|
50
77
|
def imagemagick_percent
|
|
51
78
|
offset_x = (image_info.width * percentage_to_fraction(region.x_pct)).round
|
|
52
79
|
offset_y = (image_info.height * percentage_to_fraction(region.y_pct)).round
|
|
@@ -60,6 +87,19 @@ module Riiif
|
|
|
60
87
|
"\{#{percentage_to_fraction(region.height_pct)},#{percentage_to_fraction(region.width_pct)}\}"
|
|
61
88
|
end
|
|
62
89
|
|
|
90
|
+
def vips_square
|
|
91
|
+
min, max = [image_info.width, image_info.height].minmax
|
|
92
|
+
offset = (max - min) / 2
|
|
93
|
+
|
|
94
|
+
if image_info.height >= image_info.width
|
|
95
|
+
# Portrait: left, offset, width, height
|
|
96
|
+
[0, offset, min, min]
|
|
97
|
+
else
|
|
98
|
+
# Landscape: left, offset, width, height
|
|
99
|
+
[offset, 0, min, min]
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
|
|
63
103
|
def kakadu_square
|
|
64
104
|
min, max = [image_info.width, image_info.height].minmax
|
|
65
105
|
offset = (max - min) / 2
|