travertine 0.1.0 → 0.2.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.
- data/VERSION +1 -1
- data/lib/travertine.rb +47 -1
- data/spec/data/images/kensing.jpeg +0 -0
- data/spec/data/images/kensing_2048.jpeg +0 -0
- data/spec/data/images/kensing_256.jpeg +0 -0
- data/spec/data/images/kensing_512.jpeg +0 -0
- data/spec/data/images/kensing_defaced.jpeg +0 -0
- data/spec/data/images/kensing_tile_2_0_2.jpeg +0 -0
- data/spec/spec_helper.rb +19 -0
- data/spec/travertine/travertine_spec.rb +63 -2
- data/travertine.gemspec +65 -0
- metadata +10 -3
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.2.0
|
data/lib/travertine.rb
CHANGED
@@ -1,2 +1,48 @@
|
|
1
|
-
|
1
|
+
class Travertine
|
2
|
+
|
3
|
+
# This is the correct size for Google maps tiles
|
4
|
+
DEFAULT_TILE_SIZE = 256
|
5
|
+
|
6
|
+
def self.cut_tiles(img, max_zoom, tile_size = DEFAULT_TILE_SIZE)
|
7
|
+
tile_sets = []
|
8
|
+
(0..max_zoom).collect.reverse.each do |zoom|
|
9
|
+
tiles = []
|
10
|
+
resize_to_zoom_level(img, zoom, tile_size)
|
11
|
+
tile_coordinates_for_zoom(zoom).each do |x,y|
|
12
|
+
tiles << cut_tile(img, x, y, tile_size)
|
13
|
+
end
|
14
|
+
|
15
|
+
tile_sets << tiles
|
16
|
+
end
|
17
|
+
|
18
|
+
tile_sets.reverse
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.cut_tile(img, x, y, tile_size = DEFAULT_TILE_SIZE)
|
22
|
+
tile = Magick::Image.new(tile_size, tile_size)
|
23
|
+
|
24
|
+
img_x = x * tile_size
|
25
|
+
img_y = y * tile_size
|
26
|
+
|
27
|
+
tile.import_pixels(0, 0, tile_size, tile_size, "RGBA",img.export_pixels(img_x, img_y, tile_size, tile_size, "RGBA"))
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.tile_coordinates_for_zoom(zoom_level)
|
31
|
+
[].tap do |coords|
|
32
|
+
(0..((2 ** zoom_level) - 1)).each do |x|
|
33
|
+
(0..((2 ** zoom_level) - 1)).each do |y|
|
34
|
+
coords << [x,y]
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.resize_to_zoom_level(img, zoom_level, tile_size = DEFAULT_TILE_SIZE)
|
41
|
+
size = zoom_image_size(zoom_level, tile_size)
|
42
|
+
img.resize!(size, size)
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.zoom_image_size(zoom_level, tile_size = DEFAULT_TILE_SIZE)
|
46
|
+
tile_size * (2 ** zoom_level )
|
47
|
+
end
|
2
48
|
end
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
data/spec/spec_helper.rb
CHANGED
@@ -2,4 +2,23 @@ $LOAD_PATH.unshift(File.dirname(__FILE__))
|
|
2
2
|
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
3
3
|
|
4
4
|
require 'rspec'
|
5
|
+
require 'rmagick'
|
5
6
|
require 'travertine'
|
7
|
+
|
8
|
+
def load_test_image(filename)
|
9
|
+
Magick::ImageList.new(File.join(File.dirname(__FILE__), 'data', 'images', filename)).first
|
10
|
+
end
|
11
|
+
|
12
|
+
RSpec::Matchers.define :be_same_image_as do |expected|
|
13
|
+
match do |actual|
|
14
|
+
if !((actual.columns == expected.columns) && (actual.rows == expected.rows))
|
15
|
+
false
|
16
|
+
else
|
17
|
+
mean_error_per_pixel, normalized_mean_error, normalized_max_error = actual.difference(expected)
|
18
|
+
|
19
|
+
# I'm not sure what a good normalized mean should be...
|
20
|
+
# The difference between kensing.jpeg and kensing_defaced.jpeg is 0.0156
|
21
|
+
normalized_mean_error - 0.005 < 0
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -1,7 +1,68 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Travertine do
|
4
|
-
|
5
|
-
|
4
|
+
let(:kensing) { load_test_image('kensing.jpeg') }
|
5
|
+
let(:kensing_defaced) { load_test_image('kensing_defaced.jpeg') }
|
6
|
+
let(:kensing_512) { load_test_image('kensing_512.jpeg') }
|
7
|
+
let(:kensing_256) { load_test_image('kensing_256.jpeg') }
|
8
|
+
let(:kensing_2048) { load_test_image('kensing_2048.jpeg') }
|
9
|
+
let(:kensing_tile_2_0_2) { load_test_image('kensing_tile_2_0_2.jpeg') }
|
10
|
+
|
11
|
+
describe "#cut_tiles" do
|
12
|
+
it "should cut all tiles" do
|
13
|
+
tile_sets = Travertine.cut_tiles(kensing, 2)
|
14
|
+
tile_sets.size.should == 3
|
15
|
+
|
16
|
+
tile_sets[0].size.should == 1
|
17
|
+
tile_sets[1].size.should == 4
|
18
|
+
tile_sets[2].size.should == 16
|
19
|
+
|
20
|
+
tile_sets[2][2].should be_same_image_as(kensing_tile_2_0_2)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
describe "#cut_tile" do
|
25
|
+
it "should cut the tile" do
|
26
|
+
Travertine.cut_tile(kensing, 0, 2).should be_same_image_as(kensing_tile_2_0_2)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
describe "#tile_coordinates_for_zoom" do
|
31
|
+
it "should calculate all the x,y pairs for a given zoom" do
|
32
|
+
Travertine.tile_coordinates_for_zoom(0).should == [[0,0]]
|
33
|
+
Travertine.tile_coordinates_for_zoom(1).should =~ [[0,0], [0,1], [1,0], [1,1]]
|
34
|
+
|
35
|
+
Travertine.tile_coordinates_for_zoom(2).size.should == 16
|
36
|
+
Travertine.tile_coordinates_for_zoom(2)[0..4].should =~ [[0,0], [0,1], [0,2], [0,3], [1,0]]
|
37
|
+
|
38
|
+
Travertine.tile_coordinates_for_zoom(4).size.should == 256
|
39
|
+
Travertine.tile_coordinates_for_zoom(4)[16..20].should =~ [[1,0], [1,1], [1,2], [1,3], [1,4]]
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
describe "#zoom_image_size" do
|
44
|
+
it "should calculate the size in pixels that the source image must be resized to" do
|
45
|
+
Travertine.zoom_image_size(0).should == Travertine::DEFAULT_TILE_SIZE
|
46
|
+
Travertine.zoom_image_size(2).should == Travertine::DEFAULT_TILE_SIZE * 4
|
47
|
+
Travertine.zoom_image_size(4).should == Travertine::DEFAULT_TILE_SIZE * 16
|
48
|
+
|
49
|
+
Travertine.zoom_image_size(2, 100).should == 100 * 4
|
50
|
+
Travertine.zoom_image_size(4, 1000).should == 1000 * 16
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
describe "#resize_to_zoom_level" do
|
55
|
+
it "should resize an image to the proper dimensions for the given zoom level" do
|
56
|
+
Travertine.resize_to_zoom_level(kensing, 1, 256).should be_same_image_as(kensing_512)
|
57
|
+
Travertine.resize_to_zoom_level(kensing, 3, 256).should be_same_image_as(kensing_2048)
|
58
|
+
|
59
|
+
# Just a sanity check to make sure the image compare isn't crazy.
|
60
|
+
Travertine.resize_to_zoom_level(kensing, 2, 256).should_not be_same_image_as(kensing_defaced)
|
61
|
+
end
|
62
|
+
|
63
|
+
it "should do an in-place resize, modifying the original image" do
|
64
|
+
Travertine.resize_to_zoom_level(kensing, 3, 256).columns.should == 2048
|
65
|
+
Travertine.resize_to_zoom_level(kensing, 3, 256).rows.should == 2048
|
66
|
+
end
|
6
67
|
end
|
7
68
|
end
|
data/travertine.gemspec
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{travertine}
|
8
|
+
s.version = "0.2.0"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Micah Wedemeyer"]
|
12
|
+
s.date = %q{2011-09-25}
|
13
|
+
s.description = %q{Image tiling with Ruby}
|
14
|
+
s.email = %q{me@micahwedemeyer.com}
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"LICENSE.txt",
|
17
|
+
"README.rdoc"
|
18
|
+
]
|
19
|
+
s.files = [
|
20
|
+
".document",
|
21
|
+
"Gemfile",
|
22
|
+
"Gemfile.lock",
|
23
|
+
"LICENSE.txt",
|
24
|
+
"README.rdoc",
|
25
|
+
"Rakefile",
|
26
|
+
"VERSION",
|
27
|
+
"lib/travertine.rb",
|
28
|
+
"spec/data/images/kensing.jpeg",
|
29
|
+
"spec/data/images/kensing_2048.jpeg",
|
30
|
+
"spec/data/images/kensing_256.jpeg",
|
31
|
+
"spec/data/images/kensing_512.jpeg",
|
32
|
+
"spec/data/images/kensing_defaced.jpeg",
|
33
|
+
"spec/data/images/kensing_tile_2_0_2.jpeg",
|
34
|
+
"spec/spec_helper.rb",
|
35
|
+
"spec/travertine/travertine_spec.rb",
|
36
|
+
"travertine.gemspec"
|
37
|
+
]
|
38
|
+
s.homepage = %q{http://github.com/micahwedemeyer/travertine}
|
39
|
+
s.licenses = ["MIT"]
|
40
|
+
s.require_paths = ["lib"]
|
41
|
+
s.rubygems_version = %q{1.6.2}
|
42
|
+
s.summary = %q{Image tiling with Ruby}
|
43
|
+
|
44
|
+
if s.respond_to? :specification_version then
|
45
|
+
s.specification_version = 3
|
46
|
+
|
47
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
48
|
+
s.add_runtime_dependency(%q<rmagick>, [">= 0"])
|
49
|
+
s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
|
50
|
+
s.add_development_dependency(%q<jeweler>, ["~> 1.6.4"])
|
51
|
+
s.add_development_dependency(%q<rspec>, ["~> 2.6.0"])
|
52
|
+
else
|
53
|
+
s.add_dependency(%q<rmagick>, [">= 0"])
|
54
|
+
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
55
|
+
s.add_dependency(%q<jeweler>, ["~> 1.6.4"])
|
56
|
+
s.add_dependency(%q<rspec>, ["~> 2.6.0"])
|
57
|
+
end
|
58
|
+
else
|
59
|
+
s.add_dependency(%q<rmagick>, [">= 0"])
|
60
|
+
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
61
|
+
s.add_dependency(%q<jeweler>, ["~> 1.6.4"])
|
62
|
+
s.add_dependency(%q<rspec>, ["~> 2.6.0"])
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: travertine
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 23
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
8
|
+
- 2
|
9
9
|
- 0
|
10
|
-
version: 0.
|
10
|
+
version: 0.2.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Micah Wedemeyer
|
@@ -98,8 +98,15 @@ files:
|
|
98
98
|
- Rakefile
|
99
99
|
- VERSION
|
100
100
|
- lib/travertine.rb
|
101
|
+
- spec/data/images/kensing.jpeg
|
102
|
+
- spec/data/images/kensing_2048.jpeg
|
103
|
+
- spec/data/images/kensing_256.jpeg
|
104
|
+
- spec/data/images/kensing_512.jpeg
|
105
|
+
- spec/data/images/kensing_defaced.jpeg
|
106
|
+
- spec/data/images/kensing_tile_2_0_2.jpeg
|
101
107
|
- spec/spec_helper.rb
|
102
108
|
- spec/travertine/travertine_spec.rb
|
109
|
+
- travertine.gemspec
|
103
110
|
has_rdoc: true
|
104
111
|
homepage: http://github.com/micahwedemeyer/travertine
|
105
112
|
licenses:
|