wax_iiif 0.0.2 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.rubocop.yml +25 -0
- data/.travis.yml +2 -2
- data/Gemfile +3 -2
- data/README.md +4 -4
- data/lib/wax_iiif.rb +34 -44
- data/lib/wax_iiif/base_properties.rb +90 -0
- data/lib/wax_iiif/builder.rb +252 -0
- data/lib/wax_iiif/collection.rb +58 -0
- data/lib/{iiif_s3 → wax_iiif}/config.rb +46 -60
- data/lib/{iiif_s3 → wax_iiif}/errors.rb +6 -12
- data/lib/{iiif_s3 → wax_iiif}/full_image.rb +3 -8
- data/lib/wax_iiif/image_info.rb +89 -0
- data/lib/{iiif_s3 → wax_iiif}/image_record.rb +48 -63
- data/lib/{iiif_s3 → wax_iiif}/image_tile.rb +8 -14
- data/lib/{iiif_s3 → wax_iiif}/image_variant.rb +20 -38
- data/lib/wax_iiif/manifest.rb +151 -0
- data/lib/{iiif_s3 → wax_iiif}/thumbnail.rb +5 -9
- data/lib/{iiif_s3 → wax_iiif}/utilities.rb +5 -5
- data/lib/{iiif_s3 → wax_iiif}/utilities/helpers.rb +18 -48
- data/lib/{iiif_s3 → wax_iiif}/utilities/pdf_splitter.rb +20 -23
- data/spec/base_properties_spec.rb +8 -12
- data/spec/shared_contexts.rb +28 -92
- data/spec/spec_helper.rb +3 -3
- data/spec/wax_iiif/builder_spec.rb +143 -0
- data/spec/wax_iiif/collection_spec.rb +53 -0
- data/spec/wax_iiif/config_spec.rb +15 -0
- data/spec/wax_iiif/image_info_spec.rb +57 -0
- data/spec/wax_iiif/image_record_spec.rb +82 -0
- data/spec/wax_iiif/image_variant_spec.rb +66 -0
- data/spec/wax_iiif/manifest_spec.rb +97 -0
- data/spec/wax_iiif/utilities/pdf_splitter_spec.rb +14 -0
- data/wax_iiif.gemspec +15 -19
- metadata +52 -97
- data/Guardfile +0 -10
- data/Rakefile +0 -24
- data/lib/iiif_s3/base_properties.rb +0 -95
- data/lib/iiif_s3/builder.rb +0 -241
- data/lib/iiif_s3/collection.rb +0 -61
- data/lib/iiif_s3/image_info.rb +0 -96
- data/lib/iiif_s3/manifest.rb +0 -151
- data/lib/iiif_s3/version.rb +0 -5
- data/spec/iiif_s3/builder_spec.rb +0 -152
- data/spec/iiif_s3/collection_spec.rb +0 -68
- data/spec/iiif_s3/config_spec.rb +0 -15
- data/spec/iiif_s3/image_info_spec.rb +0 -57
- data/spec/iiif_s3/image_record_spec.rb +0 -96
- data/spec/iiif_s3/image_variant_spec.rb +0 -68
- data/spec/iiif_s3/manifest_spec.rb +0 -97
- data/spec/iiif_s3/utilities/pdf_splitter_spec.rb +0 -17
- data/test.rb +0 -77
data/Guardfile
DELETED
data/Rakefile
DELETED
@@ -1,24 +0,0 @@
|
|
1
|
-
require "bundler/gem_tasks"
|
2
|
-
require "rspec/core/rake_task"
|
3
|
-
require 'yard'
|
4
|
-
|
5
|
-
RSpec::Core::RakeTask.new(:spec)
|
6
|
-
|
7
|
-
YARD::Rake::YardocTask.new do |t|
|
8
|
-
t.files = ['lib/**/*.rb'] # optional
|
9
|
-
t.stats_options = ['--list-undoc'] # optional
|
10
|
-
end
|
11
|
-
|
12
|
-
desc "Clear the screen"
|
13
|
-
task :cls do
|
14
|
-
puts "Clearing the Screen \033c"
|
15
|
-
end
|
16
|
-
|
17
|
-
task :full do
|
18
|
-
ENV["TEST_INTERNET_CONNECTIVITY"] = "yes"
|
19
|
-
ENV["SKIP_EXPENSIVE_TESTS"] = nil
|
20
|
-
end
|
21
|
-
|
22
|
-
task :default => [:cls, :spec, :yard]
|
23
|
-
|
24
|
-
task :full_test => [:full, :default]
|
@@ -1,95 +0,0 @@
|
|
1
|
-
require_relative "utilities"
|
2
|
-
module IiifS3
|
3
|
-
|
4
|
-
# Module BaseProperties provides the set of properties that are shared across
|
5
|
-
# all IIIF types. It is not a comprehensive list (yet), but it does handle
|
6
|
-
# most of the shared types. It does not include any types that have class-based
|
7
|
-
# restrictions.
|
8
|
-
#
|
9
|
-
# It also performs some basic sanity checking on (some of) the fields, and
|
10
|
-
# provides utility classes that are applicable across the fields.
|
11
|
-
#
|
12
|
-
# @todo Add within, service, seeAlso, viewingHint fields
|
13
|
-
#
|
14
|
-
# @author David Newbury <david.newbury@gmail.com>
|
15
|
-
#
|
16
|
-
module BaseProperties
|
17
|
-
include Utilities::Helpers
|
18
|
-
|
19
|
-
|
20
|
-
# @!attribute [rw] label
|
21
|
-
# @return [String] The human-readable label for this record
|
22
|
-
attr_accessor :label
|
23
|
-
# @!attribute [r] id
|
24
|
-
# @return [String] The URI for this record
|
25
|
-
attr_reader :id
|
26
|
-
# @!attribute [rw] description
|
27
|
-
# @return [String] The long-form description of this record
|
28
|
-
attr_accessor :description
|
29
|
-
# @!attribute [rw] metadata
|
30
|
-
# @return [Hash] A set of key/value pairs describing additional metadata for the object.
|
31
|
-
attr_accessor :metadata
|
32
|
-
# @!attribute [rw] attribution
|
33
|
-
# @return [String] a human-readable label, typically used for attribution or credit.
|
34
|
-
attr_accessor :attribution
|
35
|
-
# @!attribute [rw] logo
|
36
|
-
# @return [String] The URI to an image for the logo of the institution associated with this record.
|
37
|
-
attr_accessor :logo
|
38
|
-
# @!attribute [rw] license
|
39
|
-
# @return [String] The URI to a resource that describes the license or rights statement associated.
|
40
|
-
attr_accessor :license
|
41
|
-
# @!attribute [rw] related
|
42
|
-
# @return [String, Array<String>] The URI to related resources. Can be both a string or an array
|
43
|
-
attr_accessor :related
|
44
|
-
|
45
|
-
# The type of resource provided by this record.
|
46
|
-
#
|
47
|
-
# @return [String] The type of record
|
48
|
-
def type
|
49
|
-
self.class::TYPE
|
50
|
-
end
|
51
|
-
|
52
|
-
# Set the unique id for this record.
|
53
|
-
# This will automatically append the defined prefixes and suffixes.
|
54
|
-
#
|
55
|
-
# @param [String] _id The unique portion of this ID
|
56
|
-
# @return [string] The URI for this record
|
57
|
-
def id=(_id)
|
58
|
-
@id = generate_id(_id)
|
59
|
-
end
|
60
|
-
|
61
|
-
# Return the base data structure for this record as a Hash
|
62
|
-
# This will be in IIIF format, and should convert to JSON as JSON-LD nicely.
|
63
|
-
#
|
64
|
-
# @return [Hash] The base properties of this record
|
65
|
-
def base_properties
|
66
|
-
obj = {
|
67
|
-
"@context" => PRESENTATION_CONTEXT,
|
68
|
-
"@id" => self.id,
|
69
|
-
"@type" => self.type,
|
70
|
-
"label" => self.label
|
71
|
-
}
|
72
|
-
obj["attribution"] = self.attribution if self.attribution
|
73
|
-
obj["logo"] = self.logo if self.logo
|
74
|
-
obj["description"] = self.description if self.description
|
75
|
-
obj["attribution"] = self.attribution if self.attribution
|
76
|
-
obj["license"] = self.license if self.license
|
77
|
-
obj["related"] = self.related if self.related
|
78
|
-
obj["metadata"] = self.metadata if self.metadata
|
79
|
-
|
80
|
-
obj
|
81
|
-
end
|
82
|
-
|
83
|
-
# Save the JSON representation of this record to disk and to S3 (if enabled).
|
84
|
-
#
|
85
|
-
# @return [Void]
|
86
|
-
def save
|
87
|
-
save_to_disk(JSON.parse(self.to_json))
|
88
|
-
end
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
protected
|
93
|
-
|
94
|
-
end
|
95
|
-
end
|
data/lib/iiif_s3/builder.rb
DELETED
@@ -1,241 +0,0 @@
|
|
1
|
-
require_relative "utilities"
|
2
|
-
require 'pathname'
|
3
|
-
|
4
|
-
module IiifS3
|
5
|
-
class Builder
|
6
|
-
|
7
|
-
include Utilities::Helpers
|
8
|
-
|
9
|
-
HEADER_VAL = 'filename'
|
10
|
-
|
11
|
-
#
|
12
|
-
# @!attribute [r] data
|
13
|
-
# @return [Array<Hash>] The raw data computed for the given set of images
|
14
|
-
attr_reader :data
|
15
|
-
|
16
|
-
#
|
17
|
-
# @!attribute [r] manifests
|
18
|
-
# @return [Array<Hash>] The manifest hashes for this configuration
|
19
|
-
attr_accessor :manifests
|
20
|
-
|
21
|
-
# @!attribute [r] config
|
22
|
-
# @return [IiifS3::Config] The configuration object
|
23
|
-
attr_reader :config
|
24
|
-
|
25
|
-
# Initialize the builder.
|
26
|
-
#
|
27
|
-
# @param [Hash] config an optional configuration object.
|
28
|
-
# @see IiifS3::Config
|
29
|
-
# @return [Void]
|
30
|
-
#
|
31
|
-
def initialize(config = {})
|
32
|
-
@manifests = []
|
33
|
-
@config = IiifS3::Config.new(config)
|
34
|
-
end
|
35
|
-
|
36
|
-
|
37
|
-
#
|
38
|
-
# Load data into the IIIF builder.
|
39
|
-
#
|
40
|
-
# This will load the data, perform some basic verifications on it, and sort
|
41
|
-
# it into proper order.
|
42
|
-
#
|
43
|
-
# @param [Array<ImageRecord>, ImageRecord] data
|
44
|
-
# Either a single ImageRecord or an Array of ImageRecords.
|
45
|
-
# @raise [IiifS3::Error::InvalidImageData] if any of the data does
|
46
|
-
# not pass the validation checks
|
47
|
-
#
|
48
|
-
# @return [Void]
|
49
|
-
#
|
50
|
-
def load(data)
|
51
|
-
@data = [data].flatten # handle hashes and arrays of hashes
|
52
|
-
|
53
|
-
# validate
|
54
|
-
@data.each do |image_record|
|
55
|
-
raise IiifS3::Error::InvalidImageData, "Image record #{image_record.inspect} is not an ImageRecord" unless image_record.is_a? ImageRecord
|
56
|
-
raise IiifS3::Error::InvalidImageData, "Image record #{image_record.inspect} does not have an ID and/or a page number" if image_record.id.nil? || image_record.page_number.nil?
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
|
61
|
-
#
|
62
|
-
# Take the loaded data and generate all the files.
|
63
|
-
#
|
64
|
-
# @param [Boolean] force_image_generation Generate images even if they already exist
|
65
|
-
#
|
66
|
-
# @return [Void]
|
67
|
-
#
|
68
|
-
def process_data(force_image_generation=false)
|
69
|
-
return nil if @data.nil? # do nothing without data.
|
70
|
-
@manifests = []
|
71
|
-
|
72
|
-
resources = {}
|
73
|
-
@data.each do |image_record|
|
74
|
-
|
75
|
-
# image generation
|
76
|
-
#
|
77
|
-
# It attempts to load the info files and skip generation — not currently working.
|
78
|
-
info_file = image_info_file_name(image_record)
|
79
|
-
if (File.exist?(info_file) && !force_image_generation)
|
80
|
-
puts "skipping #{info_file}" if @config.verbose?
|
81
|
-
image_record.variants = load_variants(info_file)
|
82
|
-
else
|
83
|
-
image_record.variants = generate_variants(image_record, @config)
|
84
|
-
generate_tiles(image_record, @config)
|
85
|
-
generate_image_json(image_record, @config)
|
86
|
-
end
|
87
|
-
# Save the image info for the manifest
|
88
|
-
resources[image_record.id] ||= []
|
89
|
-
resources[image_record.id].push image_record
|
90
|
-
end
|
91
|
-
|
92
|
-
# Generate the manifests
|
93
|
-
resources.each do |key, val|
|
94
|
-
manifests.push generate_manifest(val, @config)
|
95
|
-
end
|
96
|
-
|
97
|
-
generate_collection
|
98
|
-
end
|
99
|
-
|
100
|
-
def generate_collection(label="top")
|
101
|
-
collection = Collection.new(label,@config)
|
102
|
-
manifests.each{|m| collection.add_manifest(m)}
|
103
|
-
collection.save
|
104
|
-
end
|
105
|
-
|
106
|
-
# Creates the required directories for exporting to the file system.
|
107
|
-
#
|
108
|
-
# @return [Void]
|
109
|
-
def create_build_directories
|
110
|
-
root_dir = generate_build_location("")
|
111
|
-
Dir.mkdir root_dir unless Dir.exists?(root_dir)
|
112
|
-
img_dir = generate_image_location("","").split("/")[0...-1].join("/")
|
113
|
-
Dir.mkdir img_dir unless Dir.exists?(img_dir)
|
114
|
-
end
|
115
|
-
|
116
|
-
# Load data into the IIIF server from a CSV
|
117
|
-
#
|
118
|
-
# @param [String] csv_path Path to the CSV file containing the image data
|
119
|
-
#
|
120
|
-
# @return [Void]
|
121
|
-
# @todo Fix this to use the correct data format!
|
122
|
-
#
|
123
|
-
def load_csv(csv_path)
|
124
|
-
raise Error::InvalidCSV unless File.exist? csv_path
|
125
|
-
begin
|
126
|
-
vals = CSV.read(csv_path)
|
127
|
-
rescue CSV::MalformedCSVError
|
128
|
-
raise Error::InvalidCSV
|
129
|
-
end
|
130
|
-
|
131
|
-
raise Error::BlankCSV if vals.length == 0
|
132
|
-
raise Error::InvalidCSV if vals[0].length != 3
|
133
|
-
|
134
|
-
# remove optional header
|
135
|
-
vals.shift if vals[0][0] == HEADER_VAL
|
136
|
-
|
137
|
-
@data = vals.collect do |data|
|
138
|
-
{
|
139
|
-
"image_path" => data[0],
|
140
|
-
"id" => data[1],
|
141
|
-
"label" => data[2]
|
142
|
-
}
|
143
|
-
end
|
144
|
-
end
|
145
|
-
|
146
|
-
protected
|
147
|
-
|
148
|
-
#----------------------------------------------------------------
|
149
|
-
def load_variants(path)
|
150
|
-
|
151
|
-
data = JSON.parse File.read(path)
|
152
|
-
id = data["@id"]
|
153
|
-
w = data["width"]
|
154
|
-
h = data["height"]
|
155
|
-
thumb_size = data["sizes"].find{|a| a["width"] == config.thumbnail_size || a["height"] == config.thumbnail_size}
|
156
|
-
thumb_w = thumb_size["width"]
|
157
|
-
thumb_h = thumb_size["height"]
|
158
|
-
full_url = "#{id}/full/full/0/default.jpg"
|
159
|
-
thumb_url = "#{id}/full/#{thumb_w},/0/default.jpg"
|
160
|
-
full = FakeImageVariant.new( id,w, h,full_url, "image/jpeg")
|
161
|
-
thumbnail = FakeImageVariant.new( id, thumb_w, thumb_h, thumb_url, "image/jpeg")
|
162
|
-
return {"full" => full, "thumbnail" => thumbnail}
|
163
|
-
end
|
164
|
-
|
165
|
-
def generate_tiles(data, config)
|
166
|
-
width = data.variants["full"].width
|
167
|
-
tile_width = config.tile_width
|
168
|
-
height = data.variants["full"].height
|
169
|
-
tiles = []
|
170
|
-
config.tile_scale_factors.each do |s|
|
171
|
-
(0..(height*1.0/(tile_width*s)).floor).each do |tileY|
|
172
|
-
(0..(width*1.0/(tile_width*s)).floor).each do |tileX|
|
173
|
-
tile = {
|
174
|
-
scale_factor: s,
|
175
|
-
xpos: tileX,
|
176
|
-
ypos: tileY,
|
177
|
-
x: tileX * tile_width * s,
|
178
|
-
y: tileY * tile_width * s,
|
179
|
-
width: tile_width * s,
|
180
|
-
height: tile_width * s,
|
181
|
-
xSize: tile_width,
|
182
|
-
ySize: tile_width
|
183
|
-
}
|
184
|
-
if (tile[:x] + tile[:width] > width)
|
185
|
-
tile[:width] = width - tile[:x]
|
186
|
-
tile[:xSize] = (tile[:width]/(s*1.0)).ceil
|
187
|
-
end
|
188
|
-
if (tile[:y] + tile[:height] > height)
|
189
|
-
tile[:height] = height - tile[:y]
|
190
|
-
tile[:ySize] = (tile[:height]/(s*1.0)).ceil
|
191
|
-
end
|
192
|
-
tiles.push(tile)
|
193
|
-
end
|
194
|
-
end
|
195
|
-
end
|
196
|
-
tiles.each do |tile|
|
197
|
-
ImageTile.new(data, @config, tile)
|
198
|
-
end
|
199
|
-
end
|
200
|
-
|
201
|
-
def image_info_file_name(data)
|
202
|
-
"#{generate_image_location(data.id,data.page_number)}/info.json"
|
203
|
-
end
|
204
|
-
|
205
|
-
def generate_image_json(data, config)
|
206
|
-
filename = image_info_file_name(data)
|
207
|
-
info = ImageInfo.new(data.variants["full"].id, data.variants ,config.tile_width, config.tile_scale_factors)
|
208
|
-
|
209
|
-
puts "writing #{filename}" if config.verbose?
|
210
|
-
Pathname.new(Pathname.new(filename).dirname).mkpath
|
211
|
-
File.open(filename, "w") do |file|
|
212
|
-
file.puts info.to_json
|
213
|
-
end
|
214
|
-
if @config.upload_to_s3
|
215
|
-
add_file_to_s3(filename)
|
216
|
-
add_default_redirect(filename)
|
217
|
-
end
|
218
|
-
return info
|
219
|
-
end
|
220
|
-
|
221
|
-
|
222
|
-
def generate_manifest(data, config)
|
223
|
-
m = Manifest.new(data, config)
|
224
|
-
m.save_all_files_to_disk
|
225
|
-
return m
|
226
|
-
end
|
227
|
-
|
228
|
-
|
229
|
-
def generate_variants(data, config)
|
230
|
-
obj = {
|
231
|
-
"full" => FullImage.new(data, config),
|
232
|
-
"thumbnail" => Thumbnail.new(data, config)
|
233
|
-
}
|
234
|
-
|
235
|
-
config.variants.each do |key,image_size|
|
236
|
-
obj[key] = ImageVariant.new(data, config, image_size)
|
237
|
-
end
|
238
|
-
return obj
|
239
|
-
end
|
240
|
-
end
|
241
|
-
end
|
data/lib/iiif_s3/collection.rb
DELETED
@@ -1,61 +0,0 @@
|
|
1
|
-
module IiifS3
|
2
|
-
|
3
|
-
#
|
4
|
-
# Class Collection is an abstraction over the IIIF Collection, which is an aggregation
|
5
|
-
# of IIIF manifests.
|
6
|
-
#
|
7
|
-
# @author David Newbury <david.newbury@gmail.com>
|
8
|
-
#
|
9
|
-
class Collection
|
10
|
-
|
11
|
-
# @return [String] The IIIF Type for collections
|
12
|
-
TYPE = "sc:Collection"
|
13
|
-
|
14
|
-
include BaseProperties
|
15
|
-
attr_reader :collections, :manifests
|
16
|
-
|
17
|
-
def initialize(label, config, name="top")
|
18
|
-
raise IiifS3::Error::MissingCollectionName if label.nil? || label.empty?
|
19
|
-
@config = config
|
20
|
-
@manifests = []
|
21
|
-
@collections = []
|
22
|
-
self.label = label
|
23
|
-
self.id = "collection/#{name}"
|
24
|
-
end
|
25
|
-
|
26
|
-
def add_collection(collection)
|
27
|
-
raise IiifS3::Error::NotACollection unless collection.respond_to?(:type) && collection.type == Collection::TYPE
|
28
|
-
@collections.push(collection)
|
29
|
-
end
|
30
|
-
|
31
|
-
def add_manifest(manifest)
|
32
|
-
raise IiifS3::Error::NotAManifest unless manifest.respond_to?(:type) && manifest.type == Manifest::TYPE
|
33
|
-
@manifests.push(manifest)
|
34
|
-
end
|
35
|
-
|
36
|
-
# The JSON representation of this collection in the IIIF-expected format
|
37
|
-
#
|
38
|
-
#
|
39
|
-
# @return [String] The JSON representation as a string
|
40
|
-
#
|
41
|
-
def to_json
|
42
|
-
obj = base_properties
|
43
|
-
obj["collections"] = collect_object(collections) unless collections.empty?
|
44
|
-
obj["manifests"] = collect_object(manifests) unless manifests.empty?
|
45
|
-
JSON.pretty_generate obj
|
46
|
-
end
|
47
|
-
|
48
|
-
protected
|
49
|
-
|
50
|
-
def collect_object(things)
|
51
|
-
things.collect do |thing|
|
52
|
-
{
|
53
|
-
"@id" => thing.id,
|
54
|
-
"@type" => thing.type,
|
55
|
-
"label" => thing.label
|
56
|
-
}
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
data/lib/iiif_s3/image_info.rb
DELETED
@@ -1,96 +0,0 @@
|
|
1
|
-
module IiifS3
|
2
|
-
|
3
|
-
#
|
4
|
-
# Class ImageInfo is a data object for the JSON representation of the image.
|
5
|
-
#
|
6
|
-
# It is designed to support the http://iiif.io/api/image/2.0/#image-information spec.
|
7
|
-
class ImageInfo
|
8
|
-
|
9
|
-
attr_accessor :id
|
10
|
-
attr_accessor :width
|
11
|
-
attr_accessor :height
|
12
|
-
attr_accessor :tile_width
|
13
|
-
attr_accessor :tile_scale_factors
|
14
|
-
|
15
|
-
def initialize(uri, variants, tile_width= nil, tile_scale_factors = nil)
|
16
|
-
|
17
|
-
raise IiifS3::Error::InvalidImageData, "No full variant provided: variants: #{variants}" unless variants["full"]
|
18
|
-
raise IiifS3::Error::InvalidImageData, "No thumbnail variant provided: variants: #{variants}" unless variants["thumbnail"]
|
19
|
-
raise IiifS3::Error::InvalidImageData, "No URI was provided for this image!" if uri.nil?
|
20
|
-
|
21
|
-
@id = uri
|
22
|
-
full = variants["full"]
|
23
|
-
@variants = variants
|
24
|
-
@width = full.width
|
25
|
-
@height = full.height
|
26
|
-
@tile_width = tile_width
|
27
|
-
@tile_scale_factors = tile_scale_factors
|
28
|
-
end
|
29
|
-
|
30
|
-
# @return [Hash] a collection of valid sizes based on the available image variants
|
31
|
-
#
|
32
|
-
def sizes
|
33
|
-
@variants.collect do |name,obj|
|
34
|
-
{"width" => obj.width, "height" => obj.height}
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
# The hash of tile information, or nil if the information does not exist.
|
39
|
-
#
|
40
|
-
#
|
41
|
-
# @return [Hash, nil] A hash of the tile metadata properly formatted for IIIF JSON.
|
42
|
-
#
|
43
|
-
def tiles
|
44
|
-
return nil if @tile_scale_factors.nil? || @tile_scale_factors.empty?
|
45
|
-
|
46
|
-
return [{
|
47
|
-
"width" => @tile_width,
|
48
|
-
"scaleFactors" => @tile_scale_factors
|
49
|
-
}]
|
50
|
-
end
|
51
|
-
|
52
|
-
|
53
|
-
# Generate the JSON data for this image in the IIIF-expected format.
|
54
|
-
#
|
55
|
-
#
|
56
|
-
# @return [String] the JSON representation of this image
|
57
|
-
#
|
58
|
-
def to_json
|
59
|
-
obj = {
|
60
|
-
"@context" => context,
|
61
|
-
"@id" => URI.escape(id),
|
62
|
-
"protocol" => protocol,
|
63
|
-
"width" => width,
|
64
|
-
"height" => height,
|
65
|
-
"sizes" => sizes,
|
66
|
-
"profile" => profile,
|
67
|
-
}
|
68
|
-
obj["tiles"] = tiles unless tiles.nil?
|
69
|
-
obj["profile"] = profile
|
70
|
-
obj["service"] = service unless service.nil?
|
71
|
-
JSON.pretty_generate obj
|
72
|
-
end
|
73
|
-
|
74
|
-
# @return [String] The IIIF context for this image
|
75
|
-
def context
|
76
|
-
IiifS3::IMAGE_CONTEXT
|
77
|
-
end
|
78
|
-
|
79
|
-
# @return [String] The IIIF protocol for this image
|
80
|
-
def protocol
|
81
|
-
IiifS3::IMAGE_PROTOCOL
|
82
|
-
end
|
83
|
-
|
84
|
-
# @return [String] The IIIF profile this image supports
|
85
|
-
def profile
|
86
|
-
[IiifS3::LEVEL_0,{
|
87
|
-
supports: ["cors","sizeByWhListed", "baseUriRedirect"]
|
88
|
-
}]
|
89
|
-
end
|
90
|
-
|
91
|
-
# TODO: Implement this. See <http://iiif.io/api/annex/services/#physical-dimensions>
|
92
|
-
def service
|
93
|
-
return nil
|
94
|
-
end
|
95
|
-
end
|
96
|
-
end
|