riiif 0.0.1 → 0.0.2
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/README.md +25 -0
- data/app/controllers/riiif/images_controller.rb +26 -0
- data/app/models/riiif/file.rb +87 -0
- data/app/models/riiif/image.rb +16 -36
- data/app/views/riiif/images/view.html.erb +21 -0
- data/config/routes.rb +5 -1
- data/lib/riiif.rb +1 -0
- data/lib/riiif/file_system_file_resolver.rb +1 -1
- data/lib/riiif/http_file_resolver.rb +24 -0
- data/lib/riiif/version.rb +1 -1
- data/riiif.gemspec +1 -2
- data/spec/controllers/images_controller_spec.rb +17 -0
- data/spec/models/image_spec.rb +45 -33
- data/spec/routing/resize_routes_spec.rb +26 -6
- data/vendor/assets/images/openseadragon/fullpage_grouphover.png +0 -0
- data/vendor/assets/images/openseadragon/fullpage_hover.png +0 -0
- data/vendor/assets/images/openseadragon/fullpage_pressed.png +0 -0
- data/vendor/assets/images/openseadragon/fullpage_rest.png +0 -0
- data/vendor/assets/images/openseadragon/home_grouphover.png +0 -0
- data/vendor/assets/images/openseadragon/home_hover.png +0 -0
- data/vendor/assets/images/openseadragon/home_pressed.png +0 -0
- data/vendor/assets/images/openseadragon/home_rest.png +0 -0
- data/vendor/assets/images/openseadragon/next_grouphover.png +0 -0
- data/vendor/assets/images/openseadragon/next_hover.png +0 -0
- data/vendor/assets/images/openseadragon/next_pressed.png +0 -0
- data/vendor/assets/images/openseadragon/next_rest.png +0 -0
- data/vendor/assets/images/openseadragon/previous_grouphover.png +0 -0
- data/vendor/assets/images/openseadragon/previous_hover.png +0 -0
- data/vendor/assets/images/openseadragon/previous_pressed.png +0 -0
- data/vendor/assets/images/openseadragon/previous_rest.png +0 -0
- data/vendor/assets/images/openseadragon/zoomin_grouphover.png +0 -0
- data/vendor/assets/images/openseadragon/zoomin_hover.png +0 -0
- data/vendor/assets/images/openseadragon/zoomin_pressed.png +0 -0
- data/vendor/assets/images/openseadragon/zoomin_rest.png +0 -0
- data/vendor/assets/images/openseadragon/zoomout_grouphover.png +0 -0
- data/vendor/assets/images/openseadragon/zoomout_hover.png +0 -0
- data/vendor/assets/images/openseadragon/zoomout_pressed.png +0 -0
- data/vendor/assets/images/openseadragon/zoomout_rest.png +0 -0
- data/vendor/assets/javascripts/openseadragon.js +12279 -0
- metadata +30 -18
- data/spec/samples/world.jp2 +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2267ef01c3a2abbf3991710ef5c4c9f6ac55500c
|
4
|
+
data.tar.gz: 13fc80e6e72c789bac048f66fc020d8a0cb2e314
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0d45589ca6d5e13de6d7a40a61b09c48e9d062118c1845d9fd786e7d8f5066980d9e1adb8d1a4b1df7b419a6729248fec8bc8ea6338d0e9216324a94d9cec7eb
|
7
|
+
data.tar.gz: 64600eb8e05f1f613b7a039ed6c25b36f5f87d75f1993b9dad667ae3eea9e47e5fe9b66200ef4a03f3fc96862e307cdc2adf936e69609206e02cd4014562553b
|
data/README.md
CHANGED
@@ -15,7 +15,32 @@ And then execute:
|
|
15
15
|
Or install it yourself as:
|
16
16
|
|
17
17
|
$ gem install riiif
|
18
|
+
|
19
|
+
## Configure
|
18
20
|
|
21
|
+
### Images on the servers file system.
|
22
|
+
|
23
|
+
By default Riiif is set to load images from the filesystem using the Riiif::FileSystemFileResolver.
|
24
|
+
You can configure how this resolver finds the files by setting this property:
|
25
|
+
```
|
26
|
+
Riiif::FileSystemFileResolver.base_path = '/opt/repository/images/'
|
27
|
+
```
|
28
|
+
When the Id passed in is "foo_image", then it will look for an image file using this glob:
|
29
|
+
```
|
30
|
+
/opt/repository/images/foo_image.{png,jpg,tiff,jp,jp2}
|
31
|
+
```
|
32
|
+
|
33
|
+
### Images retrieved over HTTP
|
34
|
+
To source the images from the network instead of the file system, we first configure Riiif to use an alternative resolver:
|
35
|
+
```
|
36
|
+
Riiif::Image.file_resolver = Riiif::HTTPFileResolver
|
37
|
+
```
|
38
|
+
Then we configure the resolver with a mechanism for mapping the provided id to a url:
|
39
|
+
```
|
40
|
+
Riiif::HTTPFileResolver.id_to_uri = lambda do |id|
|
41
|
+
"http://upload.wikimedia.org/wikipedia/commons/thumb/a/a4/#{id}.jpg/600px-#{id}.jpg"
|
42
|
+
end
|
43
|
+
```
|
19
44
|
## Usage
|
20
45
|
|
21
46
|
Mount the gem as an engine:
|
@@ -1,9 +1,35 @@
|
|
1
1
|
module Riiif
|
2
2
|
class ImagesController < ::ApplicationController
|
3
|
+
before_filter :link_header, only: [:show, :info]
|
3
4
|
def show
|
4
5
|
image = Image.new(params[:id])
|
5
6
|
data = image.render(params.permit(:region, :size, :rotation, :quality, :format))
|
6
7
|
send_data data, type: Mime::Type.lookup_by_extension(params[:format]), :disposition => 'inline'
|
7
8
|
end
|
9
|
+
|
10
|
+
def info
|
11
|
+
image = Image.new(params[:id])
|
12
|
+
render json: image.info.merge(server_info)
|
13
|
+
end
|
14
|
+
|
15
|
+
def view
|
16
|
+
@image = Image.new(params[:id])
|
17
|
+
end
|
18
|
+
|
19
|
+
protected
|
20
|
+
|
21
|
+
def link_header
|
22
|
+
response.headers["Link"] = '<http://library.stanford.edu/iiif/image-api/1.1/compliance.html#level2>;rel="profile"'
|
23
|
+
end
|
24
|
+
|
25
|
+
def server_info
|
26
|
+
{
|
27
|
+
"@context" => "http://library.stanford.edu/iiif/image-api/1.1/context.json",
|
28
|
+
"@id" => request.original_url.sub('/info.json', ''),
|
29
|
+
"formats" => Image::OUTPUT_FORMATS,
|
30
|
+
"profile" => "http://library.stanford.edu/iiif/image-api/1.1/compliance.html#level0"
|
31
|
+
|
32
|
+
}
|
33
|
+
end
|
8
34
|
end
|
9
35
|
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
require 'open3'
|
2
|
+
module Riiif
|
3
|
+
class File
|
4
|
+
include Open3
|
5
|
+
attr_reader :path
|
6
|
+
# @param input_path [String] The location of an image file
|
7
|
+
def initialize(input_path, tempfile = nil)
|
8
|
+
raise "HUH" if input_path.is_a? Riiif::File
|
9
|
+
@path = input_path
|
10
|
+
@tempfile = tempfile # ensures that the tempfile will stick around until this file is garbage collected.
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.open(file_or_url, ext = nil)
|
14
|
+
file_or_url = file_or_url.to_s # Force it to be a String... hell or highwater
|
15
|
+
if file_or_url.include?("://")
|
16
|
+
require 'open-uri'
|
17
|
+
ext ||= ::File.extname(URI.parse(file_or_url).path)
|
18
|
+
Kernel::open(file_or_url) do |f|
|
19
|
+
self.read(f, ext)
|
20
|
+
end
|
21
|
+
else
|
22
|
+
self.new(file_or_url)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.read(stream, ext)
|
27
|
+
create(ext) do |f|
|
28
|
+
while chunk = stream.read(8192)
|
29
|
+
f.write(chunk)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.create(ext = nil, validate = true, &block)
|
35
|
+
begin
|
36
|
+
tempfile = Tempfile.new(['mini_magick', ext.to_s.downcase])
|
37
|
+
tempfile.binmode
|
38
|
+
block.call(tempfile)
|
39
|
+
tempfile.close
|
40
|
+
image = self.new(tempfile.path, tempfile)
|
41
|
+
ensure
|
42
|
+
tempfile.close if tempfile
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def extract(options)
|
47
|
+
|
48
|
+
command = 'convert'
|
49
|
+
command << " -crop #{options[:crop]}" if options[:crop]
|
50
|
+
command << " -resize #{options[:size]}" if options[:size]
|
51
|
+
if options[:rotation]
|
52
|
+
command << " -virtual-pixel white +distort srt #{options[:rotation]}"
|
53
|
+
end
|
54
|
+
|
55
|
+
case options[:quality]
|
56
|
+
when 'grey'
|
57
|
+
command << ' -colorspace Gray'
|
58
|
+
when 'bitonal'
|
59
|
+
command << ' -colorspace Gray'
|
60
|
+
command << ' -type Bilevel'
|
61
|
+
end
|
62
|
+
command << " #{path} #{options[:format]}:-"
|
63
|
+
Rails.logger.debug "RIIIF executed: #{command}"
|
64
|
+
execute(command)
|
65
|
+
end
|
66
|
+
|
67
|
+
def info
|
68
|
+
return @info if @info
|
69
|
+
height, width = execute("identify -format %hx%w #{path}").split('x')
|
70
|
+
@info = {height: Integer(height), width: Integer(width)}
|
71
|
+
end
|
72
|
+
|
73
|
+
private
|
74
|
+
def execute(command)
|
75
|
+
stdin, stdout, stderr, wait_thr = popen3(command)
|
76
|
+
stdin.close
|
77
|
+
stdout.binmode
|
78
|
+
out = stdout.read
|
79
|
+
stdout.close
|
80
|
+
err = stderr.read
|
81
|
+
stderr.close
|
82
|
+
raise "Unable to execute command \"#{command}\"\n#{err}" unless wait_thr.value.success?
|
83
|
+
out
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
87
|
+
end
|
data/app/models/riiif/image.rb
CHANGED
@@ -1,37 +1,30 @@
|
|
1
|
-
require 'mini_magick'
|
2
1
|
module Riiif
|
3
2
|
class Image
|
3
|
+
|
4
4
|
class_attribute :file_resolver
|
5
5
|
self.file_resolver = FileSystemFileResolver
|
6
6
|
|
7
|
-
|
7
|
+
OUTPUT_FORMATS = %W{jpg png}
|
8
|
+
|
9
|
+
attr_reader :path_name, :id
|
8
10
|
|
9
11
|
# @param [String] id The identifier of the file
|
10
12
|
def initialize(id)
|
13
|
+
@id = id
|
11
14
|
@path_name = file_resolver.find(id)
|
12
15
|
end
|
13
16
|
|
14
17
|
def render(args)
|
15
18
|
options = decode_options!(args)
|
19
|
+
Rails.cache.fetch(options.merge(id: id), compress: true, expires_in: 3.days) do
|
20
|
+
image.extract(options)
|
21
|
+
end
|
22
|
+
end
|
16
23
|
|
17
|
-
|
18
|
-
c.crop options[:crop] if options[:crop]
|
19
|
-
c.resize options[:size] if options[:size]
|
20
|
-
if options[:rotation]
|
21
|
-
c.virtual_pixel 'white'
|
22
|
-
c.distort.+ 'srt', options[:rotation]
|
23
|
-
end
|
24
|
+
delegate :info, to: :image
|
24
25
|
|
25
|
-
|
26
|
-
|
27
|
-
c.colorspace "Gray"
|
28
|
-
when 'bitonal'
|
29
|
-
c.colorspace "Gray"
|
30
|
-
c.type 'Bilevel'
|
31
|
-
end
|
32
|
-
end
|
33
|
-
image.format(options[:format])
|
34
|
-
image.to_blob
|
26
|
+
def image
|
27
|
+
@image ||= Riiif::File.open(path_name)
|
35
28
|
end
|
36
29
|
|
37
30
|
private
|
@@ -63,7 +56,7 @@ module Riiif
|
|
63
56
|
end
|
64
57
|
|
65
58
|
def validate_format!(format)
|
66
|
-
raise InvalidAttributeError, "Unsupported format: #{format}" unless
|
59
|
+
raise InvalidAttributeError, "Unsupported format: #{format}" unless OUTPUT_FORMATS.include?(format)
|
67
60
|
|
68
61
|
end
|
69
62
|
|
@@ -72,8 +65,8 @@ module Riiif
|
|
72
65
|
nil
|
73
66
|
elsif md = /^pct:(\d+),(\d+),(\d+),(\d+)$/.match(region)
|
74
67
|
# Image magic can't do percentage offsets, so we have to calculate it
|
75
|
-
offset_x = (
|
76
|
-
offset_y = (
|
68
|
+
offset_x = (info[:width] * Integer(md[1]).to_f / 100).round
|
69
|
+
offset_y = (info[:height] * Integer(md[2]).to_f / 100).round
|
77
70
|
"#{md[3]}%x#{md[4]}+#{offset_x}+#{offset_y}"
|
78
71
|
elsif md = /^(\d+),(\d+),(\d+),(\d+)$/.match(region)
|
79
72
|
"#{md[3]}x#{md[4]}+#{md[1]}+#{md[2]}"
|
@@ -89,7 +82,7 @@ module Riiif
|
|
89
82
|
"x#{md[1]}"
|
90
83
|
elsif md = /^(\d+),$/.match(size)
|
91
84
|
"#{md[1]}"
|
92
|
-
elsif md = /^pct:(\d+)$/.match(size)
|
85
|
+
elsif md = /^pct:(\d+(.\d+)?)$/.match(size)
|
93
86
|
"#{md[1]}%"
|
94
87
|
elsif md = /^(\d+),(\d+)$/.match(size)
|
95
88
|
"#{md[1]}x#{md[2]}!"
|
@@ -100,18 +93,5 @@ module Riiif
|
|
100
93
|
end
|
101
94
|
end
|
102
95
|
|
103
|
-
def image
|
104
|
-
begin
|
105
|
-
@image ||= MiniMagick::Image.open(path_name)
|
106
|
-
rescue Errno::ENOENT => e
|
107
|
-
Rails.logger.error "Unable to find #{path_name}"
|
108
|
-
Rails.logger.error e.backtrace
|
109
|
-
raise Riiif::Error, "Unable to find #{path_name}"
|
110
|
-
rescue MiniMagick::Error => e
|
111
|
-
Rails.logger.error "Error trying to open #{path_name}"
|
112
|
-
Rails.logger.error e.backtrace
|
113
|
-
raise Riiif::Error, "Unable to open the image #{path_name}"
|
114
|
-
end
|
115
|
-
end
|
116
96
|
end
|
117
97
|
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
<div id="openseadragon1" style="width: 800px; height: 600px;"></div>
|
2
|
+
<%=javascript_include_tag "openseadragon.js" %>
|
3
|
+
<script type="text/javascript">
|
4
|
+
var viewer = OpenSeadragon({
|
5
|
+
id: "openseadragon1",
|
6
|
+
prefixUrl: "/assets/openseadragon/",
|
7
|
+
tileSources: [{
|
8
|
+
"image_host": "http://localhost:8080/image-service",
|
9
|
+
"identifier": "irises",
|
10
|
+
"width": 4264,
|
11
|
+
"height": 3282,
|
12
|
+
"scale_factors": [1, 2, 3, 4, 5],
|
13
|
+
"tile_width": 1024,
|
14
|
+
"tile_height": 1024,
|
15
|
+
"formats": [ "jpg", "png" ],
|
16
|
+
"qualities": ["native", "bitonal", "grey", "color"],
|
17
|
+
"profile": "http://library.stanford.edu/iiif/image-api/compliance.html#level1"
|
18
|
+
}]
|
19
|
+
});
|
20
|
+
</script>
|
21
|
+
DOOD
|
data/config/routes.rb
CHANGED
@@ -1,4 +1,8 @@
|
|
1
1
|
Riiif::Engine.routes.draw do
|
2
2
|
ALLOW_DOTS ||= /[\w.]+/
|
3
|
-
|
3
|
+
PERCENTAGE ||= /(pct:)?[\w.]+/
|
4
|
+
get "/:id/:region/:size/:rotation/:quality(.:format)" => "images#show",
|
5
|
+
constraints: { rotation: ALLOW_DOTS, size: PERCENTAGE}
|
6
|
+
get "/:id/info(.:format)" => "images#info", :constraints => { :format => /json/}
|
7
|
+
get "/:id/view(.:format)" => "images#view"
|
4
8
|
end
|
data/lib/riiif.rb
CHANGED
@@ -13,7 +13,7 @@ module Riiif
|
|
13
13
|
|
14
14
|
def self.pattern(id)
|
15
15
|
raise ArgumentException, "Invalid characters in id `#{id}`" unless /^\w+$/.match(id)
|
16
|
-
File.join(base_path, "#{id}.{#{input_types.join(',')}}")
|
16
|
+
::File.join(base_path, "#{id}.{#{input_types.join(',')}}")
|
17
17
|
end
|
18
18
|
|
19
19
|
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Riiif
|
2
|
+
module HTTPFileResolver
|
3
|
+
|
4
|
+
# Set a lambda that maps the first parameter (id) to a URL
|
5
|
+
# Example:
|
6
|
+
#
|
7
|
+
# Riiif::HTTPFileResolver.id_to_uri = lambda do |id|
|
8
|
+
# "http://upload.wikimedia.org/wikipedia/commons/thumb/a/a4/#{id}.jpg/600px-#{id}.jpg"
|
9
|
+
# end
|
10
|
+
#
|
11
|
+
mattr_accessor :id_to_uri
|
12
|
+
|
13
|
+
def self.find(id)
|
14
|
+
uri(id)
|
15
|
+
end
|
16
|
+
|
17
|
+
protected
|
18
|
+
|
19
|
+
def self.uri(id)
|
20
|
+
raise "Must set the id_to_uri lambda" if id_to_uri.nil?
|
21
|
+
id_to_uri.call(id)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
data/lib/riiif/version.rb
CHANGED
data/riiif.gemspec
CHANGED
@@ -13,7 +13,7 @@ Gem::Specification.new do |spec|
|
|
13
13
|
spec.homepage = ""
|
14
14
|
spec.license = "APACHE2"
|
15
15
|
|
16
|
-
spec.files = `git ls-files`.split($/)
|
16
|
+
spec.files = `git ls-files|grep -v spec/samples`.split($/)
|
17
17
|
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
18
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
19
|
spec.require_paths = ["lib"]
|
@@ -22,6 +22,5 @@ Gem::Specification.new do |spec|
|
|
22
22
|
spec.add_development_dependency "rake"
|
23
23
|
spec.add_development_dependency "engine_cart"
|
24
24
|
spec.add_development_dependency "rspec-rails"
|
25
|
-
spec.add_dependency 'mini_magick'
|
26
25
|
spec.add_dependency 'rails', '> 3.2.0'
|
27
26
|
end
|
@@ -12,5 +12,22 @@ describe Riiif::ImagesController do
|
|
12
12
|
rotation: '0', quality: 'native', format: 'jpg'
|
13
13
|
expect(response).to be_successful
|
14
14
|
expect(response.body).to eq 'IMAGEDATA'
|
15
|
+
expect(response.headers['Link']).to eq '<http://library.stanford.edu/iiif/image-api/1.1/compliance.html#level2>;rel="profile"'
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should return info" do
|
19
|
+
image = double
|
20
|
+
expect(Riiif::Image).to receive(:new).with('abcd1234').and_return(image)
|
21
|
+
expect(image).to receive(:info).and_return({width: 6000, height: 4000 })
|
22
|
+
get :info, id: 'abcd1234', format: 'json'
|
23
|
+
expect(response).to be_successful
|
24
|
+
json = JSON.parse(response.body)
|
25
|
+
expect(json).to eq "@context"=>"http://library.stanford.edu/iiif/image-api/1.1/context.json",
|
26
|
+
"@id" =>"http://test.host/image-service/abcd1234",
|
27
|
+
"width" =>6000,
|
28
|
+
"height" =>4000,
|
29
|
+
"formats" => [ "jpg", "png" ],
|
30
|
+
"profile" => "http://library.stanford.edu/iiif/image-api/1.1/compliance.html#level0"
|
31
|
+
expect(response.headers['Link']).to eq '<http://library.stanford.edu/iiif/image-api/1.1/compliance.html#level2>;rel="profile"'
|
15
32
|
end
|
16
33
|
end
|
data/spec/models/image_spec.rb
CHANGED
@@ -1,15 +1,12 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Riiif::Image do
|
4
|
+
before { Rails.cache.clear }
|
5
|
+
let(:filename) { File.expand_path('spec/samples/world.jp2') }
|
4
6
|
subject { Riiif::Image.new('world') }
|
5
7
|
describe "happy path" do
|
6
|
-
let(:combinator) { double }
|
7
|
-
let(:inner) { double }
|
8
8
|
before do
|
9
|
-
expect(
|
10
|
-
expect(inner).to receive(:to_blob).and_return('imagedata')
|
11
|
-
inner.stub(:combine_options).and_yield(combinator)
|
12
|
-
subject.stub(:image).and_return(inner)
|
9
|
+
expect(subject.image).to receive(:execute).with("convert #{filename} jpg:-").and_return('imagedata')
|
13
10
|
end
|
14
11
|
it "should render" do
|
15
12
|
expect(subject.render('size' => 'full', format: 'jpg')).to eq 'imagedata'
|
@@ -22,27 +19,42 @@ describe Riiif::Image do
|
|
22
19
|
end
|
23
20
|
end
|
24
21
|
|
22
|
+
describe "info" do
|
23
|
+
it "should return the data" do
|
24
|
+
expect(subject.info).to eq height: 400, width:800
|
25
|
+
end
|
26
|
+
end
|
25
27
|
|
26
|
-
describe "
|
27
|
-
let(:combinator) { double }
|
28
|
-
let(:inner) { double(format: true, to_blob: 'imagedata') }
|
28
|
+
describe "get images from web" do
|
29
29
|
before do
|
30
|
-
|
31
|
-
|
30
|
+
Riiif::Image.file_resolver = Riiif::HTTPFileResolver
|
31
|
+
Riiif::HTTPFileResolver.id_to_uri = lambda do |id|
|
32
|
+
"http://upload.wikimedia.org/wikipedia/commons/thumb/a/a4/#{id}.jpg/600px-#{id}.jpg"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
after do
|
36
|
+
Riiif::Image.file_resolver = Riiif::FileSystemFileResolver
|
37
|
+
end
|
38
|
+
subject { Riiif::Image.new('Cave_26,_Ajanta') }
|
39
|
+
it "should be easy" do
|
40
|
+
expect(subject.info).to eq height: 390, width:600
|
32
41
|
end
|
42
|
+
end
|
43
|
+
|
44
|
+
|
45
|
+
describe "mogrify" do
|
33
46
|
describe "region" do
|
34
47
|
it "should return the original when specifing full size" do
|
35
|
-
expect(
|
48
|
+
expect(subject.image).to receive(:execute).with("convert #{filename} png:-")
|
36
49
|
subject.render(region: 'full', format: 'png')
|
37
50
|
end
|
38
51
|
it "should handle absolute geometry" do
|
39
|
-
expect(
|
52
|
+
expect(subject.image).to receive(:execute).with("convert -crop 60x75+80+15 #{filename} png:-")
|
40
53
|
subject.render(region: '80,15,60,75', format: 'png')
|
41
54
|
end
|
42
55
|
it "should handle percent geometry" do
|
43
|
-
expect(
|
44
|
-
expect(
|
45
|
-
expect(combinator).to receive(:crop).with('80%x70+18+13')
|
56
|
+
expect(subject.image).to receive(:execute).with("identify -format %hx%w #{filename}").and_return('131x175')
|
57
|
+
expect(subject.image).to receive(:execute).with("convert -crop 80%x70+18+13 #{filename} png:-")
|
46
58
|
subject.render(region: 'pct:10,10,80,70', format: 'png')
|
47
59
|
end
|
48
60
|
it "should raise an error for invalid geometry" do
|
@@ -52,27 +64,31 @@ describe Riiif::Image do
|
|
52
64
|
|
53
65
|
describe "resize" do
|
54
66
|
it "should return the original when specifing full size" do
|
55
|
-
expect(
|
67
|
+
expect(subject.image).to receive(:execute).with("convert #{filename} png:-")
|
56
68
|
subject.render(size: 'full', format: 'png')
|
57
69
|
end
|
58
|
-
it "should handle percent sizes" do
|
59
|
-
expect(
|
70
|
+
it "should handle integer percent sizes" do
|
71
|
+
expect(subject.image).to receive(:execute).with("convert -resize 50% #{filename} png:-")
|
60
72
|
subject.render(size: 'pct:50', format: 'png')
|
61
73
|
end
|
74
|
+
it "should handle float percent sizes" do
|
75
|
+
expect(subject.image).to receive(:execute).with("convert -resize 12.5% #{filename} png:-")
|
76
|
+
subject.render(size: 'pct:12.5', format: 'png')
|
77
|
+
end
|
62
78
|
it "should handle w," do
|
63
|
-
expect(
|
79
|
+
expect(subject.image).to receive(:execute).with("convert -resize 50 #{filename} png:-")
|
64
80
|
subject.render(size: '50,', format: 'png')
|
65
81
|
end
|
66
82
|
it "should handle ,h" do
|
67
|
-
expect(
|
83
|
+
expect(subject.image).to receive(:execute).with("convert -resize x50 #{filename} png:-")
|
68
84
|
subject.render(size: ',50', format: 'png')
|
69
85
|
end
|
70
86
|
it "should handle w,h" do
|
71
|
-
expect(
|
87
|
+
expect(subject.image).to receive(:execute).with("convert -resize 150x75! #{filename} png:-")
|
72
88
|
subject.render(size: '150,75', format: 'png')
|
73
89
|
end
|
74
90
|
it "should handle bestfit (!w,h)" do
|
75
|
-
expect(
|
91
|
+
expect(subject.image).to receive(:execute).with("convert -resize 150x75 #{filename} png:-")
|
76
92
|
subject.render(size: '!150,75', format: 'png')
|
77
93
|
end
|
78
94
|
it "should raise an error for invalid size" do
|
@@ -81,15 +97,12 @@ describe Riiif::Image do
|
|
81
97
|
end
|
82
98
|
|
83
99
|
describe "rotate" do
|
84
|
-
let(:distorter) { double }
|
85
100
|
it "should return the original when specifing full size" do
|
86
|
-
expect(
|
101
|
+
expect(subject.image).to receive(:execute).with("convert #{filename} png:-")
|
87
102
|
subject.render(rotation: '0', format: 'png')
|
88
103
|
end
|
89
104
|
it "should handle floats" do
|
90
|
-
expect(
|
91
|
-
expect(combinator).to receive(:virtual_pixel).with('white')
|
92
|
-
expect(distorter).to receive(:+).with("srt", 22.5)
|
105
|
+
expect(subject.image).to receive(:execute).with("convert -virtual-pixel white +distort srt 22.5 #{filename} png:-")
|
93
106
|
subject.render(rotation: '22.5', format: 'png')
|
94
107
|
end
|
95
108
|
it "should raise an error for invalid angle" do
|
@@ -99,20 +112,19 @@ describe Riiif::Image do
|
|
99
112
|
|
100
113
|
describe "quality" do
|
101
114
|
it "should return the original when specifing native" do
|
102
|
-
expect(
|
115
|
+
expect(subject.image).to receive(:execute).with("convert #{filename} png:-")
|
103
116
|
subject.render(quality: 'native', format: 'png')
|
104
117
|
end
|
105
118
|
it "should return the original when specifing color" do
|
106
|
-
expect(
|
119
|
+
expect(subject.image).to receive(:execute).with("convert #{filename} png:-")
|
107
120
|
subject.render(quality: 'color', format: 'png')
|
108
121
|
end
|
109
122
|
it "should convert to grayscale" do
|
110
|
-
expect(
|
123
|
+
expect(subject.image).to receive(:execute).with("convert -colorspace Gray #{filename} png:-")
|
111
124
|
subject.render(quality: 'grey', format: 'png')
|
112
125
|
end
|
113
126
|
it "should convert to bitonal" do
|
114
|
-
expect(
|
115
|
-
expect(combinator).to receive(:type).with('Bilevel')
|
127
|
+
expect(subject.image).to receive(:execute).with("convert -colorspace Gray -type Bilevel #{filename} png:-")
|
116
128
|
subject.render(quality: 'bitonal', format: 'png')
|
117
129
|
end
|
118
130
|
it "should raise an error for invalid angle" do
|