djatoka 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.
- data/LICENSE +21 -0
- data/README.rdoc +105 -0
- data/Rakefile +62 -0
- data/VERSION +1 -0
- data/bin/djatoka_url +65 -0
- data/generators/djatoka/djatoka_generator.rb +32 -0
- data/generators/djatoka/templates/OpenLayers.js +1743 -0
- data/generators/djatoka/templates/OpenURL.js +256 -0
- data/generators/djatoka/templates/blank.gif +0 -0
- data/generators/djatoka/templates/djatoka-initializer.rb +4 -0
- data/generators/djatoka/templates/djatoka.js +48 -0
- data/generators/djatoka/templates/east-mini.png +0 -0
- data/generators/djatoka/templates/north-mini.png +0 -0
- data/generators/djatoka/templates/south-mini.png +0 -0
- data/generators/djatoka/templates/west-mini.png +0 -0
- data/generators/djatoka/templates/zoom-minus-mini.png +0 -0
- data/generators/djatoka/templates/zoom-plus-mini.png +0 -0
- data/generators/djatoka/templates/zoom-world-mini.png +0 -0
- data/lib/djatoka.rb +71 -0
- data/lib/djatoka/common.rb +125 -0
- data/lib/djatoka/metadata.rb +76 -0
- data/lib/djatoka/net.rb +25 -0
- data/lib/djatoka/region.rb +134 -0
- data/lib/djatoka/resolver.rb +83 -0
- data/lib/djatoka/view_helpers.rb +106 -0
- data/test/helper.rb +24 -0
- data/test/test_common.rb +64 -0
- data/test/test_djatoka.rb +28 -0
- data/test/test_metadata.rb +84 -0
- data/test/test_region.rb +151 -0
- data/test/test_resolver.rb +88 -0
- data/test/test_view_helpers.rb +15 -0
- metadata +145 -0
@@ -0,0 +1,256 @@
|
|
1
|
+
/* Copyright (c) UNC Chapel Hill University Library, created by Hugh A. Cayless
|
2
|
+
* and revised by J. Clifford Dyer. Published under the Clear BSD licence.
|
3
|
+
* See http://svn.openlayers.org/trunk/openlayers/license.txt for the full
|
4
|
+
* text of the license.
|
5
|
+
*/
|
6
|
+
|
7
|
+
|
8
|
+
/**
|
9
|
+
* @requires OpenLayers/Layer/Grid.js
|
10
|
+
* @requires OpenLayers/Tile/Image.js
|
11
|
+
*/
|
12
|
+
|
13
|
+
/**
|
14
|
+
* Class: OpenLayers.Layer.OpenURL
|
15
|
+
*
|
16
|
+
* Inherits from:
|
17
|
+
* - <OpenLayers.Layer.Grid>
|
18
|
+
*/
|
19
|
+
OpenLayers.Layer.OpenURL = OpenLayers.Class(OpenLayers.Layer.Grid, {
|
20
|
+
|
21
|
+
/**
|
22
|
+
* APIProperty: isBaseLayer
|
23
|
+
* {Boolean}
|
24
|
+
*/
|
25
|
+
isBaseLayer: true,
|
26
|
+
|
27
|
+
/**
|
28
|
+
* APIProperty: tileOrigin
|
29
|
+
* {<OpenLayers.Pixel>}
|
30
|
+
*/
|
31
|
+
tileOrigin: null,
|
32
|
+
|
33
|
+
url_ver: 'Z39.88-2004',
|
34
|
+
rft_id: null,
|
35
|
+
svc_id: "info:lanl-repo/svc/getRegion",
|
36
|
+
svc_val_fmt: "info:ofi/fmt:kev:mtx:jpeg2000",
|
37
|
+
format: null,
|
38
|
+
tileHeight: null,
|
39
|
+
|
40
|
+
/**
|
41
|
+
* Constructor: OpenLayers.Layer.OpenURL
|
42
|
+
*
|
43
|
+
* Parameters:
|
44
|
+
* name - {String}
|
45
|
+
* url - {String}
|
46
|
+
* options - {Object} Hashtable of extra options to tag onto the layer
|
47
|
+
*/
|
48
|
+
initialize: function(name, url, options) {
|
49
|
+
var newArguments = [];
|
50
|
+
newArguments.push(name, url, {}, options);
|
51
|
+
OpenLayers.Layer.Grid.prototype.initialize.apply(this, newArguments);
|
52
|
+
this.rft_id = options.rft_id;
|
53
|
+
this.format = options.format;
|
54
|
+
// Get image metadata if it hasn't been set
|
55
|
+
if (!options.imgMetadata) {
|
56
|
+
var request = OpenLayers.Request.issue({url: options.metadataUrl, async: false});
|
57
|
+
this.imgMetadata = eval('(' + request.responseText + ')');
|
58
|
+
} else {
|
59
|
+
this.imgMetadata = options.imgMetadata;
|
60
|
+
}
|
61
|
+
|
62
|
+
var minLevel = this.getMinLevel();
|
63
|
+
|
64
|
+
// viewerLevel is the smallest useful zoom level: i.e., it is the largest level that fits entirely
|
65
|
+
// within the bounds of the viewer div.
|
66
|
+
var viewerLevel = Math.ceil(Math.min(minLevel, Math.max(
|
67
|
+
(Math.log(this.imgMetadata.width) - Math.log(OpenLayers.Layer.OpenURL.viewerWidth)),
|
68
|
+
(Math.log(this.imgMetadata.height) - Math.log(OpenLayers.Layer.OpenURL.viewerHeight)))/
|
69
|
+
Math.log(2)));
|
70
|
+
this.zoomOffset = minLevel - viewerLevel;
|
71
|
+
|
72
|
+
// width at level viewerLevel
|
73
|
+
var w = this.imgMetadata.width / Math.pow(2, viewerLevel);
|
74
|
+
|
75
|
+
// height at level viewerLevel
|
76
|
+
var h = this.imgMetadata.height / Math.pow(2, viewerLevel);
|
77
|
+
|
78
|
+
this.resolutions = new Array();
|
79
|
+
for (i = viewerLevel; i >= 0; i--) {
|
80
|
+
this.resolutions.push(Math.pow(2, i));
|
81
|
+
}
|
82
|
+
|
83
|
+
this.tileSize = new OpenLayers.Size(Math.ceil(w), Math.ceil(h));
|
84
|
+
},
|
85
|
+
|
86
|
+
/**
|
87
|
+
* APIMethod:destroy
|
88
|
+
*/
|
89
|
+
destroy: function() {
|
90
|
+
// for now, nothing special to do here.
|
91
|
+
OpenLayers.Layer.Grid.prototype.destroy.apply(this, arguments);
|
92
|
+
},
|
93
|
+
|
94
|
+
|
95
|
+
/**
|
96
|
+
* APIMethod: clone
|
97
|
+
*
|
98
|
+
* Parameters:
|
99
|
+
* obj - {Object}
|
100
|
+
*
|
101
|
+
* Returns:
|
102
|
+
* {<OpenLayers.Layer.OpenURL>} An exact clone of this <OpenLayers.Layer.OpenURL>
|
103
|
+
*/
|
104
|
+
clone: function (obj) {
|
105
|
+
|
106
|
+
if (obj == null) {
|
107
|
+
obj = new OpenLayers.Layer.OpenURL(this.name,
|
108
|
+
this.url,
|
109
|
+
this.options);
|
110
|
+
}
|
111
|
+
|
112
|
+
//get all additions from superclasses
|
113
|
+
obj = OpenLayers.Layer.Grid.prototype.clone.apply(this, [obj]);
|
114
|
+
|
115
|
+
// copy/set any non-init, non-simple values here
|
116
|
+
|
117
|
+
return obj;
|
118
|
+
},
|
119
|
+
|
120
|
+
/**
|
121
|
+
* Method: getURL
|
122
|
+
*
|
123
|
+
* Parameters:
|
124
|
+
* bounds - {<OpenLayers.Bounds>}
|
125
|
+
*
|
126
|
+
* Returns:
|
127
|
+
* {String} A string with the layer's url and parameters and also the
|
128
|
+
* passed-in bounds and appropriate tile size specified as
|
129
|
+
* parameters
|
130
|
+
*/
|
131
|
+
getURL: function (bounds) {
|
132
|
+
bounds = this.adjustBounds(bounds);
|
133
|
+
this.calculatePositionAndSize(bounds);
|
134
|
+
var z = this.map.getZoom() + this.zoomOffset;
|
135
|
+
var path = OpenLayers.Layer.OpenURL.djatokaURL + "?url_ver=" + this.url_ver + "&rft_id=" + this.rft_id +
|
136
|
+
"&svc_id=" + this.svc_id + "&svc_val_fmt=" + this.svc_val_fmt + "&svc.format=" +
|
137
|
+
this.format + "&svc.level=" + z + "&svc.rotate=0&svc.region=" + this.tilePos.lat + "," +
|
138
|
+
this.tilePos.lon + "," + this.imageSize.h + "," + this.imageSize.w;
|
139
|
+
|
140
|
+
var url = this.url;
|
141
|
+
if (url instanceof Array) {
|
142
|
+
url = this.selectUrl(path, url);
|
143
|
+
}
|
144
|
+
return url + path;
|
145
|
+
},
|
146
|
+
|
147
|
+
/**
|
148
|
+
* Method: addTile
|
149
|
+
* addTile creates a tile, initializes it, and adds it to the layer div.
|
150
|
+
*
|
151
|
+
* Parameters:
|
152
|
+
* bounds - {<OpenLayers.Bounds>}
|
153
|
+
* position - {<OpenLayers.Pixel>}
|
154
|
+
*
|
155
|
+
* Returns:
|
156
|
+
* {<OpenLayers.Tile.Image>} The added OpenLayers.Tile.Image
|
157
|
+
*/
|
158
|
+
addTile:function(bounds,position) {
|
159
|
+
this.calculatePositionAndSize(bounds);
|
160
|
+
var size = this.size;
|
161
|
+
return new OpenLayers.Tile.Image(this, position, bounds,
|
162
|
+
null, this.imageSize);
|
163
|
+
},
|
164
|
+
|
165
|
+
/**
|
166
|
+
* APIMethod: setMap
|
167
|
+
* When the layer is added to a map, then we can fetch our origin
|
168
|
+
* (if we don't have one.)
|
169
|
+
*
|
170
|
+
* Parameters:
|
171
|
+
* map - {<OpenLayers.Map>}
|
172
|
+
*/
|
173
|
+
setMap: function(map) {
|
174
|
+
OpenLayers.Layer.Grid.prototype.setMap.apply(this, arguments);
|
175
|
+
if (!this.tileOrigin) {
|
176
|
+
this.tileOrigin = new OpenLayers.LonLat(this.map.maxExtent.left,
|
177
|
+
this.map.maxExtent.bottom);
|
178
|
+
}
|
179
|
+
},
|
180
|
+
|
181
|
+
calculatePositionAndSize: function(bounds) {
|
182
|
+
// Have to recalculate x and y (instead of using bounds and resolution), because resolution will be off.
|
183
|
+
// Get number of tiles in image
|
184
|
+
var max = this.map.getMaxExtent();
|
185
|
+
var xtiles = Math.round( 1 / (this.tileSize.w / max.getWidth()));
|
186
|
+
// Find out which tile we're on
|
187
|
+
var xpos = Math.round((bounds.left / max.getWidth()) * xtiles);
|
188
|
+
// Set x
|
189
|
+
var x = xpos * (this.tileSize.w + 1);
|
190
|
+
var w,h;
|
191
|
+
var xExtent = max.getWidth() / this.map.getResolution();
|
192
|
+
if (xpos == xtiles - 1) {
|
193
|
+
w = xExtent % (this.tileSize.w + 1);
|
194
|
+
} else {
|
195
|
+
w = this.tileSize.w;
|
196
|
+
}
|
197
|
+
// Do the same for y
|
198
|
+
var ytiles = Math.round( 1 / (this.tileSize.h / max.getHeight()));
|
199
|
+
// Djatoka's coordinate system is top-down, not bottom-up, so invert for y
|
200
|
+
var y = max.getHeight() - bounds.top;
|
201
|
+
y = y < 0? 0 : y;
|
202
|
+
var ypos = Math.round((y / max.getHeight()) * ytiles);
|
203
|
+
var y = ypos * (this.tileSize.h + 1);
|
204
|
+
var yExtent = max.getHeight() / this.map.getResolution();
|
205
|
+
if (ypos == ytiles - 1) {
|
206
|
+
h = yExtent % (this.tileSize.h + 1);
|
207
|
+
} else {
|
208
|
+
h = this.tileSize.h;
|
209
|
+
}
|
210
|
+
this.tilePos = new OpenLayers.LonLat(x,y);
|
211
|
+
this.imageSize = new OpenLayers.Size(w,h);
|
212
|
+
},
|
213
|
+
|
214
|
+
getImageMetadata: function() {
|
215
|
+
return this.imgMetadata;
|
216
|
+
},
|
217
|
+
|
218
|
+
getResolutions: function() {
|
219
|
+
return this.resolutions;
|
220
|
+
},
|
221
|
+
|
222
|
+
getTileSize: function() {
|
223
|
+
return this.tileSize;
|
224
|
+
},
|
225
|
+
|
226
|
+
getMinLevel: function() {
|
227
|
+
// Versions of djatoka from before 4/17/09 have levels set to the
|
228
|
+
// number of levels encoded in the image. After this date, that
|
229
|
+
// number is assigned to the new dwtLevels, and levels contains the
|
230
|
+
// number of levels between the full image size and the minimum
|
231
|
+
// size djatoka could return. We want the lesser of these two numbers.
|
232
|
+
|
233
|
+
var levelsInImg;
|
234
|
+
var levelsToDjatokaMin;
|
235
|
+
if (this.imgMetadata.dwtLevels === undefined) {
|
236
|
+
var maxImgDimension = Math.max(this.imgMetadata.width,
|
237
|
+
this.imgMetadata.height);
|
238
|
+
levelsInImg = this.imgMetadata.levels;
|
239
|
+
levelsToDjatokaMin = Math.floor((Math.log(maxImgDimension) -
|
240
|
+
Math.log(OpenLayers.Layer.OpenURL.minDjatokaLevelDimension)) /
|
241
|
+
Math.log(2));
|
242
|
+
} else {
|
243
|
+
var levelsInImg = this.imgMetadata.dwtLevels;
|
244
|
+
var levelsToDjatokaMin = this.imgMetadata.levels;
|
245
|
+
}
|
246
|
+
return Math.min(levelsInImg, levelsToDjatokaMin);
|
247
|
+
},
|
248
|
+
|
249
|
+
CLASS_NAME: "OpenLayers.Layer.OpenURL"
|
250
|
+
});
|
251
|
+
|
252
|
+
OpenLayers.Layer.OpenURL.viewerWidth = 512;
|
253
|
+
OpenLayers.Layer.OpenURL.viewerHeight = 512;
|
254
|
+
OpenLayers.Layer.OpenURL.minDjatokaLevelDimension = 48;
|
255
|
+
OpenLayers.Layer.OpenURL.djatokaURL = '/adore-djatoka/resolver';
|
256
|
+
|
Binary file
|
@@ -0,0 +1,48 @@
|
|
1
|
+
//////////////////////
|
2
|
+
//$.extend({
|
3
|
+
// getUrlVars: function(){
|
4
|
+
// var vars = [], hash;
|
5
|
+
// var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&');
|
6
|
+
// for(var i = 0; i < hashes.length; i++)
|
7
|
+
// {
|
8
|
+
// hash = hashes[i].split('=');
|
9
|
+
// vars.push(hash[0]);
|
10
|
+
// vars[hash[0]] = hash[1];
|
11
|
+
// }
|
12
|
+
// return vars;
|
13
|
+
// },
|
14
|
+
// getUrlVar: function(name){
|
15
|
+
// return $.getUrlVars()[name];
|
16
|
+
// }
|
17
|
+
//});
|
18
|
+
//////////////////////////////
|
19
|
+
|
20
|
+
function openlayersInit(base_url,metadataUrl, rft_id, div_identifier){
|
21
|
+
|
22
|
+
//alert(params);
|
23
|
+
//var metadataUrl = "http://localhost/adore-djatoka/resolver?url_ver=Z39.88-2004&rft_id=http://memory.loc.gov/gmd/gmd433/g4330/g4330/np000066.jp2&svc_id=info:lanl-repo/svc/getMetadata";
|
24
|
+
|
25
|
+
var OUlayer = new OpenLayers.Layer.OpenURL( "OpenURL",
|
26
|
+
base_url, {layername: 'basic',
|
27
|
+
format:'image/jpeg',
|
28
|
+
rft_id: rft_id,
|
29
|
+
metadataUrl: metadataUrl} );
|
30
|
+
var metadata = OUlayer.getImageMetadata();
|
31
|
+
var resolutions = OUlayer.getResolutions();
|
32
|
+
var maxExtent = new OpenLayers.Bounds(0, 0, metadata.width,
|
33
|
+
metadata.height);
|
34
|
+
var tileSize = OUlayer.getTileSize();
|
35
|
+
var options = {resolutions: resolutions, maxExtent: maxExtent,
|
36
|
+
tileSize: tileSize};
|
37
|
+
var map = new OpenLayers.Map( div_identifier, options);
|
38
|
+
map.addLayer(OUlayer);
|
39
|
+
var lon = metadata.width / 2;
|
40
|
+
var lat = metadata.height / 2;
|
41
|
+
map.setCenter(new OpenLayers.LonLat(lon, lat), 0);
|
42
|
+
}
|
43
|
+
///////////////////////////////////////
|
44
|
+
// $(document).ready(function() {
|
45
|
+
// openlayersInit('http://localhost',"http://localhost/adore-djatoka/resolver?url_ver=Z39.88-2004&rft_id=http://memory.loc.gov/gmd/gmd433/g4330/g4330/np000066.jp2&svc_id=info:lanl-repo/svc/getMetadata",
|
46
|
+
// 'http://memory.loc.gov/gmd/gmd433/g4330/g4330/np000066.jp2');
|
47
|
+
// });
|
48
|
+
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
data/lib/djatoka.rb
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
$:.unshift(File.dirname(__FILE__)) unless
|
2
|
+
$:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
|
3
|
+
|
4
|
+
# In the context of Djatoka a <tt>uri</tt> is an Addressable::URI and a
|
5
|
+
# <tt>url</tt> is a String representation of that uri.
|
6
|
+
module Djatoka
|
7
|
+
# for use with Rails to allow for configuration
|
8
|
+
def self.resolver=(url)
|
9
|
+
if url.is_a? Djatoka::Resolver
|
10
|
+
@resolver = url
|
11
|
+
elsif url.is_a? String
|
12
|
+
@resolver = Djatoka::Resolver.new(url)
|
13
|
+
# if resolver.valid?
|
14
|
+
# @resolver = resolver
|
15
|
+
# else
|
16
|
+
# @resolver = nil
|
17
|
+
# end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
def self.resolver
|
21
|
+
@resolver
|
22
|
+
end
|
23
|
+
|
24
|
+
# Allows for using curb if available. Otherwise falls back on Net::HTTP. See Djatoka::Net
|
25
|
+
def self.use_curb=(curb)
|
26
|
+
@use_curb = curb
|
27
|
+
end
|
28
|
+
def self.use_curb?
|
29
|
+
@use_curb
|
30
|
+
end
|
31
|
+
class << self
|
32
|
+
# Calls enable_actionpack
|
33
|
+
def enable
|
34
|
+
enable_actionpack
|
35
|
+
end
|
36
|
+
# Requires the Djatoka Rails view helpers
|
37
|
+
def enable_actionpack
|
38
|
+
return if ActionView::Base.instance_methods.include? :djatoka_image_tag
|
39
|
+
require 'djatoka/view_helpers'
|
40
|
+
ActionView::Base.send :include, ViewHelpers
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
begin
|
46
|
+
require 'curb'
|
47
|
+
Djatoka.use_curb = true
|
48
|
+
rescue LoadError
|
49
|
+
Djatoka.use_curb = false
|
50
|
+
end
|
51
|
+
|
52
|
+
require 'net/http'
|
53
|
+
require 'uri'
|
54
|
+
|
55
|
+
require 'djatoka/net'
|
56
|
+
require 'djatoka/resolver'
|
57
|
+
require 'djatoka/metadata'
|
58
|
+
require 'djatoka/common'
|
59
|
+
require 'djatoka/region'
|
60
|
+
|
61
|
+
require 'rubygems'
|
62
|
+
require 'addressable/uri'
|
63
|
+
require 'addressable/template'
|
64
|
+
require 'json'
|
65
|
+
require 'mash'
|
66
|
+
|
67
|
+
|
68
|
+
if defined? Rails
|
69
|
+
Djatoka.enable_actionpack if defined? ActionController
|
70
|
+
end
|
71
|
+
|
@@ -0,0 +1,125 @@
|
|
1
|
+
# In this module are some methods for some common operations to be done on images.
|
2
|
+
# These features are more experimental and more likely to break for some images
|
3
|
+
# at some resolutions.
|
4
|
+
module Djatoka::Common
|
5
|
+
|
6
|
+
# svc.region - Y,X,H,W.
|
7
|
+
# Y is the down inset value (positive) from 0 on the y axis at the max image resolution.
|
8
|
+
# X is the right inset value (positive) from 0 on the x axis at the max image resolution.
|
9
|
+
# H is the height of the image provided as response.
|
10
|
+
# W is the width of the image provided as response.
|
11
|
+
|
12
|
+
# Sets the scale to a 75x75 pixel version of the image and crops any long side
|
13
|
+
# to square it. Returns self (a Djatoka::Region.)
|
14
|
+
def smallbox
|
15
|
+
scale('75')
|
16
|
+
square_params
|
17
|
+
self
|
18
|
+
end
|
19
|
+
|
20
|
+
# An Addressable::URI for a 75x75 version of the image.
|
21
|
+
def smallbox_uri
|
22
|
+
smallbox
|
23
|
+
uri
|
24
|
+
end
|
25
|
+
|
26
|
+
# String of #smallbox_uri
|
27
|
+
def smallbox_url
|
28
|
+
smallbox_uri.to_s
|
29
|
+
end
|
30
|
+
|
31
|
+
# public alias for #square_params. Returns self (a Djatoka::Region)
|
32
|
+
def square
|
33
|
+
square_params
|
34
|
+
self
|
35
|
+
end
|
36
|
+
|
37
|
+
# Sets any parameters needed to crop the image to a square and then returns
|
38
|
+
# an Addressable::URI.
|
39
|
+
def square_uri
|
40
|
+
square_params
|
41
|
+
uri
|
42
|
+
end
|
43
|
+
|
44
|
+
# String of the #square_uri
|
45
|
+
def square_url
|
46
|
+
square_uri.to_s
|
47
|
+
end
|
48
|
+
|
49
|
+
# So far we figure the best level to ask for based on any scale parameter and
|
50
|
+
# try to compensate for any difference between the dwtLevels and djatoka levels
|
51
|
+
# so that we get a decent image returned.
|
52
|
+
def pick_best_level(metadata)
|
53
|
+
best_level = '6'
|
54
|
+
metadata_levels = metadata.all_levels
|
55
|
+
metadata_levels.keys.sort.reverse.each do |k|
|
56
|
+
if metadata_levels[k].height.to_i > query.scale.to_i and
|
57
|
+
metadata_levels[k].width.to_i > query.scale.to_i
|
58
|
+
best_level = k
|
59
|
+
end
|
60
|
+
end
|
61
|
+
# Here we try to compensate for when the dwtLevels does not match the
|
62
|
+
# djatoka levels.
|
63
|
+
if metadata.dwt_levels.to_i > metadata.levels.to_i
|
64
|
+
best_level.to_i - 2
|
65
|
+
elsif metadata.dwt_levels.to_i == metadata.levels.to_i
|
66
|
+
best_level.to_i
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
private
|
71
|
+
|
72
|
+
# This is an experimental way to get a decent looking square image at any level.
|
73
|
+
# The complication seems to come in where the dwtLevels are different from the
|
74
|
+
# how djatoka determines levels. See the comments for the places where the code
|
75
|
+
# tries to reconcile this difference in a way that seems to work in the cases
|
76
|
+
# seen so far.
|
77
|
+
def square_params
|
78
|
+
metadata = Djatoka::Metadata.new(resolver, rft_id).perform
|
79
|
+
if metadata
|
80
|
+
orig_height = metadata.height.to_i
|
81
|
+
orig_width = metadata.width.to_i
|
82
|
+
if query.scale and query.scale.split.length == 1
|
83
|
+
# scaling an image without picking a good level results in poor image
|
84
|
+
# quality
|
85
|
+
level(pick_best_level(metadata))
|
86
|
+
end
|
87
|
+
if query.level
|
88
|
+
# we try to compensate for when there is a difference between the
|
89
|
+
# dwtLevels and the djatoka levels. So far the only case seen is where
|
90
|
+
# the dwtLevels are greater than the djatoka levels.
|
91
|
+
if metadata.dwt_levels.to_i > metadata.levels.to_i
|
92
|
+
good_query_level = query.level.to_i + 1
|
93
|
+
# dwtLevels in the cases seen so far almost always match the djatoka levels.
|
94
|
+
elsif metadata.dwt_levels.to_i == metadata.levels.to_i
|
95
|
+
good_query_level = query.level.to_i
|
96
|
+
end
|
97
|
+
height = metadata.all_levels[good_query_level].height
|
98
|
+
width = metadata.all_levels[good_query_level].width
|
99
|
+
else
|
100
|
+
height = orig_height
|
101
|
+
width = orig_width
|
102
|
+
end
|
103
|
+
# x & y are always the inset of the original image size
|
104
|
+
# height and width are relative to the level selected and one if not already
|
105
|
+
# a square then the longest side is cropped.
|
106
|
+
if height != width
|
107
|
+
if height > width
|
108
|
+
x = '0'
|
109
|
+
y = ((orig_height - orig_width)/2).to_s
|
110
|
+
|
111
|
+
h = width.to_s
|
112
|
+
w = width.to_s
|
113
|
+
elsif width > height
|
114
|
+
y = '0'
|
115
|
+
x = ((orig_width - orig_height)/2).to_s
|
116
|
+
h = height.to_s
|
117
|
+
w = height.to_s
|
118
|
+
end
|
119
|
+
region([y,x,h,w])
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end #square_params
|
123
|
+
|
124
|
+
end
|
125
|
+
|