Class: Tiler

Inherits:
Object
  • Object
show all
Defined in:
lib/imagetiler.rb

Constant Summary collapse

TILE_SIZE =
256

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeTiler

Returns a new instance of Tiler.



31
32
33
34
35
36
37
38
# File 'lib/imagetiler.rb', line 31

def initialize()
	@zoom_levels = 0..4
	@bg_color = Magick::Pixel.new(255,255,255,Magick::TransparentOpacity)
	@format = "png"
	@autocreate_dirs = true
	@output_dir = "."
	@prefix = "tile"
end

Instance Attribute Details

#autocreate_dirsObject

Returns the value of attribute autocreate_dirs.



28
29
30
# File 'lib/imagetiler.rb', line 28

def autocreate_dirs
  @autocreate_dirs
end

#bg_colorObject

Returns the value of attribute bg_color.



28
29
30
# File 'lib/imagetiler.rb', line 28

def bg_color
  @bg_color
end

#formatObject

Returns the value of attribute format.



28
29
30
# File 'lib/imagetiler.rb', line 28

def format
  @format
end

#output_dirObject

Returns the value of attribute output_dir.



28
29
30
# File 'lib/imagetiler.rb', line 28

def output_dir
  @output_dir
end

#prefixObject

Returns the value of attribute prefix.



28
29
30
# File 'lib/imagetiler.rb', line 28

def prefix
  @prefix
end

#zoom_levelsObject

Returns the value of attribute zoom_levels.



28
29
30
# File 'lib/imagetiler.rb', line 28

def zoom_levels
  @zoom_levels
end

Instance Method Details

#calc_native_res_zoom(image_source) ⇒ Object

Calculates the zoom level closest to native resolution. Returns a float for the zoom – so, use zoom.ceil if you want the higher zoom, for example



85
86
87
88
89
90
91
# File 'lib/imagetiler.rb', line 85

def calc_native_res_zoom(image_source)
	image = get_image(image_source)
	side_length = calc_side_length(image)
	zoom = log2(side_length)-log2(TILE_SIZE)
	zoom = 0 if zoom < 0
	zoom
end

#calc_side_length(image) ⇒ Object



113
114
115
116
117
118
# File 'lib/imagetiler.rb', line 113

def calc_side_length(image)
	long_side = [image.columns, image.rows].max
	max_zoom = @zoom_levels.max
	ceil = (long_side.to_f()/2**max_zoom).ceil
	side_length = ceil*2**max_zoom
end

#create_dir(dir) ⇒ Object

if dir does not exist, create it



121
122
123
124
125
# File 'lib/imagetiler.rb', line 121

def create_dir(dir)
	if !FileTest::directory?(dir)
		Dir::mkdir(dir)
	end
end

#get_image(image_source) ⇒ Object



103
104
105
106
107
108
109
110
111
# File 'lib/imagetiler.rb', line 103

def get_image(image_source)
	case image_source
	when Magick::Image
		image = image_source
	else
		image = Magick::ImageList::new(image_source)
	end
	return image
end

#log2(x) ⇒ Object



127
128
129
# File 'lib/imagetiler.rb', line 127

def log2(x)
	Math.log(x)/Math.log(2)
end

#make_tiles(image_source, opts = {}) ⇒ Object

image_source can either be an RMagick Image or a string specifying the filename



41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/imagetiler.rb', line 41

def make_tiles(image_source, opts={})

	# initializing and setting options and stuff
	image = get_image(image_source)
	opts.each_pair do |key,value|
      instance_variable_set "@#{key}", value
   end

	if @autocreate_dirs
		create_dir(output_dir)
	end

	# pad image with background color so image is square
	image_sq = pad_image(image)
	image_length = image_sq.columns

	# the actual tiling part!
	zoom_levels.each do |zoom|
		# get the number of tiles in each column and row
		factor = 2 ** zoom

		# get length of tiles for current zoom
		tile_length = image_length / factor

		0.upto(factor-1) do |col|
			0.upto(factor-1) do |row|

				# cut tile
				# Image.crop(x,y,width,height,toss offset information)
				tile = image_sq.crop(col*tile_length, row*tile_length,
														 tile_length, tile_length, true)
				tile.resize!(TILE_SIZE,TILE_SIZE)

				# output tile
				filename = File.join(@output_dir, "#{prefix}_#{zoom}_#{col}_#{row}.#{@format}")
				tile.write(filename)
			end
		end
	end
end

#pad_image(image) ⇒ Object

pad image to the lower right with bg_color so that the image is square and that the max number of pixels is evenly divisible by the max number of tiles per side



96
97
98
99
100
101
# File 'lib/imagetiler.rb', line 96

def pad_image(image)
	dim = calc_side_length(image)
	
	image.background_color = @bg_color
	image.extent(dim, dim)
end