imagetiler 0.1.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/README.markdown +65 -0
- data/Rakefile +15 -0
- data/VERSION +1 -0
- data/imagetiler.gemspec +41 -0
- data/imagetiler.rb +197 -0
- metadata +71 -0
data/README.markdown
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
# imagetiler -- A simple tool to tile images.
|
2
|
+
|
3
|
+
imagetiler is a simple command-line and ruby image tiler with support for multiple zoom levels and different image formats.
|
4
|
+
|
5
|
+
|
6
|
+
## How to use
|
7
|
+
|
8
|
+
#### From the command line
|
9
|
+
|
10
|
+
`ruby tile_image.rb -o OUTPUT_DIR -z ZOOM_LEVELS IMAGE_FILE`
|
11
|
+
|
12
|
+
For example
|
13
|
+
|
14
|
+
`ruby tile_image.rb -o ./tiles -z 2..4 ./input_files/map.jpg`
|
15
|
+
|
16
|
+
|
17
|
+
#### From ruby
|
18
|
+
|
19
|
+
`require 'imagetiler'
|
20
|
+
t = Tiler.new
|
21
|
+
t.make_tiles(image_source, opts)`
|
22
|
+
|
23
|
+
`image_source` can be either a filename or an RMagick Image.
|
24
|
+
|
25
|
+
You can set options two ways:
|
26
|
+
`t.zoom_levels = 2..4`
|
27
|
+
or
|
28
|
+
`t.get_tiles(image, :zoom_levels => 2..4)`
|
29
|
+
|
30
|
+
Setting options in the get_tiles function sets them for that instance of Tiler.
|
31
|
+
|
32
|
+
|
33
|
+
## Methods
|
34
|
+
|
35
|
+
`make_tiles(image_source, opts)`
|
36
|
+
|
37
|
+
`calc_native_res_zoom` : Calculates the zoom level closest to native resolution. Returns a float for the zoom -- so, use zoom.round if you want the closest zoom level, for example
|
38
|
+
|
39
|
+
|
40
|
+
## Output
|
41
|
+
Tiles in the output folder with format
|
42
|
+
`#{output_dir}/#{prefix}_#{zoom_level}_#{tile_col}_#{tile_row}.#{image_format}`
|
43
|
+
|
44
|
+
|
45
|
+
## Options
|
46
|
+
|
47
|
+
`zoom_levels` : Zoom level 0 shows the entire image as one 256x256 tile. Subsequent zoom levels double both the horizontal and vertical sides. Default is 0..4
|
48
|
+
`output_dir` : Defaults to the current directory. Don't include the ending '/'
|
49
|
+
`bg_color` : The background fill color, transparent by default.
|
50
|
+
`autocreate_dirs` : Whether or not to create the directory if it exists. Default true
|
51
|
+
`format` : The format for the output, defaults to 'jpg'. Can be png, gif, etc.
|
52
|
+
`prefix` : Prefix for the output files. Defaults to 'tile'
|
53
|
+
|
54
|
+
## Other things
|
55
|
+
* Requires rmagick.
|
56
|
+
* Might not work on Windows as written -- change the '/' for the output to '\\'
|
57
|
+
|
58
|
+
|
59
|
+
## Credits
|
60
|
+
This tiler is modified Guilhem's tile_image.rb tool, which is part of the ym4r project. The Tiler itself has been re-written, and TileParam is no longer used.
|
61
|
+
Thanks to Guilhem for the command-line portions and the sample ruby and rmagick code!
|
62
|
+
|
63
|
+
|
64
|
+
## License
|
65
|
+
imagetiler uses the MIT License.
|
data/Rakefile
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
begin
|
2
|
+
require 'jeweler'
|
3
|
+
Jeweler::Tasks.new do |gemspec|
|
4
|
+
gemspec.name = "imagetiler"
|
5
|
+
gemspec.summary = "Simple image tiler"
|
6
|
+
gemspec.description = "imagetiler is a simple command-line and ruby image tiler with support for multiple zoom levels and different image formats."
|
7
|
+
gemspec.email = "tanna22@gmail.com"
|
8
|
+
gemspec.homepage = "http://github.com/fofanafi/imagetiler"
|
9
|
+
gemspec.authors = ["Anna, Guilhem Vellut"]
|
10
|
+
end
|
11
|
+
Jeweler::GemcutterTasks.new
|
12
|
+
rescue LoadError
|
13
|
+
puts "Jeweler not available. Install it with: gem install jeweler"
|
14
|
+
end
|
15
|
+
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.0
|
data/imagetiler.gemspec
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{imagetiler}
|
8
|
+
s.version = "0.1.0"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Anna, Guilhem Vellut"]
|
12
|
+
s.date = %q{2010-08-31}
|
13
|
+
s.description = %q{imagetiler is a simple command-line and ruby image tiler with support for multiple zoom levels and different image formats.}
|
14
|
+
s.email = %q{tanna22@gmail.com}
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"README.markdown"
|
17
|
+
]
|
18
|
+
s.files = [
|
19
|
+
"README.markdown",
|
20
|
+
"Rakefile",
|
21
|
+
"VERSION",
|
22
|
+
"imagetiler.gemspec",
|
23
|
+
"imagetiler.rb"
|
24
|
+
]
|
25
|
+
s.homepage = %q{http://github.com/fofanafi/imagetiler}
|
26
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
27
|
+
s.require_paths = ["lib"]
|
28
|
+
s.rubygems_version = %q{1.3.7}
|
29
|
+
s.summary = %q{Simple image tiler}
|
30
|
+
|
31
|
+
if s.respond_to? :specification_version then
|
32
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
33
|
+
s.specification_version = 3
|
34
|
+
|
35
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
36
|
+
else
|
37
|
+
end
|
38
|
+
else
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
data/imagetiler.rb
ADDED
@@ -0,0 +1,197 @@
|
|
1
|
+
# Copyright (c) 2010 Anna <tanna22@gmail.com>
|
2
|
+
# Copyright (c) 2006 Guilhem Vellut <guilhem.vellut+ym4r@gmail.com>
|
3
|
+
#
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy of this software
|
5
|
+
# and associated documentation files (the "Software"), to deal in the Software without
|
6
|
+
# restriction, including without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
# distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
|
8
|
+
# Software is furnished to do so, subject to the following conditions:
|
9
|
+
#
|
10
|
+
# The above copyright notice and this permission notice shall be included in all copies or
|
11
|
+
# substantial portions of the Software.
|
12
|
+
#
|
13
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
|
14
|
+
# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
15
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
16
|
+
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
17
|
+
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
18
|
+
|
19
|
+
require 'rubygems'
|
20
|
+
require 'RMagick'
|
21
|
+
require 'optparse'
|
22
|
+
require 'ostruct'
|
23
|
+
|
24
|
+
class Tiler
|
25
|
+
|
26
|
+
TILE_SIZE = 256
|
27
|
+
|
28
|
+
attr_accessor(:output_dir, :zoom_levels, :bg_color,
|
29
|
+
:format, :autocreate_dirs, :prefix)
|
30
|
+
|
31
|
+
def initialize()
|
32
|
+
@zoom_levels = 0..4
|
33
|
+
@bg_color = Magick::Pixel.new(255,255,255,0)
|
34
|
+
@format = "jpg"
|
35
|
+
@autocreate_dirs = true
|
36
|
+
@output_dir = "."
|
37
|
+
@prefix = "tile"
|
38
|
+
end
|
39
|
+
|
40
|
+
# image_source can either be an RMagick Image or a string specifying the filename
|
41
|
+
def make_tiles(image_source, opts={})
|
42
|
+
|
43
|
+
# initializing and setting options and stuff
|
44
|
+
image = get_image(image_source)
|
45
|
+
if opts[:zoom_levels]
|
46
|
+
@zoom_levels = opts[:zoom_levels]
|
47
|
+
end
|
48
|
+
if opts[:bg_color] then @bg_color = opts[:bg_color] end
|
49
|
+
if opts[:format] then @format = opts[:format] end
|
50
|
+
if opts[:autocreate_dirs] then @autocreate_dirs = opts[:autocreate_dirs] end
|
51
|
+
if opts[:output_dir] then @output_dir = opts[:output_dir] end
|
52
|
+
@prefix = opts[:prefix] if opts[:prefix]
|
53
|
+
|
54
|
+
if @autocreate_dirs
|
55
|
+
create_dir(output_dir)
|
56
|
+
end
|
57
|
+
|
58
|
+
# pad image with background color so image is square
|
59
|
+
image_sq = pad_image(image)
|
60
|
+
image_length = image_sq.columns
|
61
|
+
|
62
|
+
zoom_levels.each do |zoom|
|
63
|
+
# get the number of tiles in each column and row
|
64
|
+
factor = 2 ** zoom
|
65
|
+
|
66
|
+
# get length of tiles for current zoom
|
67
|
+
tile_length = image_length / factor
|
68
|
+
|
69
|
+
0.upto(factor-1) do |col|
|
70
|
+
0.upto(factor-1) do |row|
|
71
|
+
# Image.crop(x,y,width,height,toss offset information)
|
72
|
+
tile = image_sq.crop(col*tile_length, row*tile_length,
|
73
|
+
tile_length, tile_length, true)
|
74
|
+
tile.resize!(TILE_SIZE,TILE_SIZE)
|
75
|
+
tile.write("#{@output_dir}/#{prefix}_#{zoom}_#{col}_#{row}.#{@format}")
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
# Calculates the zoom level closest to native resolution.
|
82
|
+
# Returns a float for the zoom -- so, use zoom.ceil if you
|
83
|
+
# want the higher zoom, for example
|
84
|
+
def calc_native_res_zoom(image_source)
|
85
|
+
image = get_image(image_source)
|
86
|
+
side_length = calc_side_length(image)
|
87
|
+
zoom = log2(side_length)-log2(TILE_SIZE)
|
88
|
+
zoom = 0 if zoom < 0
|
89
|
+
zoom
|
90
|
+
end
|
91
|
+
|
92
|
+
# pad image to the lower right with bg_color so that the
|
93
|
+
# image is square and that the max number of pixels
|
94
|
+
# is evenly divisible by the max number of tiles per side
|
95
|
+
def pad_image(image)
|
96
|
+
dimension_image = calc_side_length(image)
|
97
|
+
puts dimension_image
|
98
|
+
|
99
|
+
bg_color = @bg_color
|
100
|
+
image_sq = Magick::Image.new(dimension_image, dimension_image) do
|
101
|
+
self.background_color = bg_color
|
102
|
+
end
|
103
|
+
|
104
|
+
image_sq.import_pixels(0,0,image.columns,image.rows,"RGBA",image.export_pixels(0,0,image.columns,image.rows,"RGBA"))
|
105
|
+
end
|
106
|
+
|
107
|
+
def get_image(image_source)
|
108
|
+
case image_source
|
109
|
+
when Magick::Image
|
110
|
+
image = image_source
|
111
|
+
else
|
112
|
+
image = Magick::ImageList::new(image_source)
|
113
|
+
end
|
114
|
+
return image
|
115
|
+
end
|
116
|
+
|
117
|
+
def calc_side_length(image)
|
118
|
+
long_side = [image.columns, image.rows].max
|
119
|
+
max_zoom = @zoom_levels.max
|
120
|
+
ceil = (long_side.to_f()/2**max_zoom).ceil
|
121
|
+
side_length = ceil*2**max_zoom
|
122
|
+
end
|
123
|
+
|
124
|
+
# if dir does not exist, create it
|
125
|
+
def create_dir(dir)
|
126
|
+
if !FileTest::directory?(dir)
|
127
|
+
Dir::mkdir(dir)
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
def log2(x)
|
132
|
+
Math.log(x)/Math.log(2)
|
133
|
+
end
|
134
|
+
|
135
|
+
end
|
136
|
+
|
137
|
+
# Runs this as a script
|
138
|
+
def main
|
139
|
+
|
140
|
+
OptionParser.accept(Range, /(\d+)\.\.(\d+)/) do |range,start,finish|
|
141
|
+
Range.new(start.to_i,finish.to_i)
|
142
|
+
end
|
143
|
+
|
144
|
+
OptionParser.accept(Magick::Pixel,/(\d+),(\d+),(\d+),(\d+)/) do |pixel, r,g,b,a|
|
145
|
+
Magick::Pixel.new(r.to_f,g.to_f,b.to_f,a.to_f)
|
146
|
+
end
|
147
|
+
|
148
|
+
options = {}
|
149
|
+
|
150
|
+
opts = OptionParser.new do |opts|
|
151
|
+
opts.banner = "Image Tiler for Google Maps\nUsage: tile_image.rb [options] IMAGE_FILE \nExample: tile_image.rb -o ./tiles -z 11..12 -p 602,768,11,78,112,1.91827348 ./input_files/map.jpg"
|
152
|
+
opts.separator ""
|
153
|
+
opts.on("-o","--output OUTPUT_DIR","Directory where the tiles will be created") do |dir|
|
154
|
+
options[:output_dir] = dir
|
155
|
+
end
|
156
|
+
opts.on("-f","--format FORMAT","Image format in which to get the file (gif, jpeg, png...). Is jpg by default") do |format|
|
157
|
+
options[:format] = format
|
158
|
+
end
|
159
|
+
opts.on("-z","--zoom_levels ZOOM_RANGE",Range,"Range of zoom values at which the tiles must be generated. Is 0..4 by default") do |range|
|
160
|
+
options[:zoom_levels] = range
|
161
|
+
end
|
162
|
+
opts.on("-b","--background COLOR",Magick::Pixel,"Background color components. Is fully transparent par default") do |bg|
|
163
|
+
options[:bg_color] = bg
|
164
|
+
end
|
165
|
+
opts.on("-p","--prefix PREFIX","Prefix to file output. Is 'tile' by default") do |prefix|
|
166
|
+
options[:prefix] = prefix
|
167
|
+
end
|
168
|
+
opts.on_tail("-h", "--help", "Show this message") do
|
169
|
+
puts opts
|
170
|
+
exit
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
opts.parse!(ARGV)
|
175
|
+
|
176
|
+
#test the presence of all the options and exit with an error message
|
177
|
+
error = []
|
178
|
+
error << "No output directory defined (-o,--output)" if options[:output_dir].nil?
|
179
|
+
error << "No input files defined" if ARGV.empty?
|
180
|
+
|
181
|
+
unless error.empty?
|
182
|
+
puts error * "\n" + "\n\n"
|
183
|
+
puts opts
|
184
|
+
exit
|
185
|
+
end
|
186
|
+
|
187
|
+
t = Tiler.new
|
188
|
+
t.make_tiles(ARGV[0], options) # ignore all input files but first
|
189
|
+
|
190
|
+
end
|
191
|
+
|
192
|
+
# Executes the main method if this file is being run as a script.
|
193
|
+
if $0 == __FILE__
|
194
|
+
main
|
195
|
+
end
|
196
|
+
|
197
|
+
|
metadata
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: imagetiler
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 27
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
- 0
|
10
|
+
version: 0.1.0
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Anna, Guilhem Vellut
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2010-08-31 00:00:00 -04:00
|
19
|
+
default_executable:
|
20
|
+
dependencies: []
|
21
|
+
|
22
|
+
description: imagetiler is a simple command-line and ruby image tiler with support for multiple zoom levels and different image formats.
|
23
|
+
email: tanna22@gmail.com
|
24
|
+
executables: []
|
25
|
+
|
26
|
+
extensions: []
|
27
|
+
|
28
|
+
extra_rdoc_files:
|
29
|
+
- README.markdown
|
30
|
+
files:
|
31
|
+
- README.markdown
|
32
|
+
- Rakefile
|
33
|
+
- VERSION
|
34
|
+
- imagetiler.gemspec
|
35
|
+
- imagetiler.rb
|
36
|
+
has_rdoc: true
|
37
|
+
homepage: http://github.com/fofanafi/imagetiler
|
38
|
+
licenses: []
|
39
|
+
|
40
|
+
post_install_message:
|
41
|
+
rdoc_options:
|
42
|
+
- --charset=UTF-8
|
43
|
+
require_paths:
|
44
|
+
- lib
|
45
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
46
|
+
none: false
|
47
|
+
requirements:
|
48
|
+
- - ">="
|
49
|
+
- !ruby/object:Gem::Version
|
50
|
+
hash: 3
|
51
|
+
segments:
|
52
|
+
- 0
|
53
|
+
version: "0"
|
54
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
55
|
+
none: false
|
56
|
+
requirements:
|
57
|
+
- - ">="
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
hash: 3
|
60
|
+
segments:
|
61
|
+
- 0
|
62
|
+
version: "0"
|
63
|
+
requirements: []
|
64
|
+
|
65
|
+
rubyforge_project:
|
66
|
+
rubygems_version: 1.3.7
|
67
|
+
signing_key:
|
68
|
+
specification_version: 3
|
69
|
+
summary: Simple image tiler
|
70
|
+
test_files: []
|
71
|
+
|