Skip to content

Instantly share code, notes, and snippets.

@akanieski
Forked from miletbaker/map_tile.rb
Last active August 29, 2015 14:02
Show Gist options
  • Save akanieski/a05e961e7f262765f1e4 to your computer and use it in GitHub Desktop.
Save akanieski/a05e961e7f262765f1e4 to your computer and use it in GitHub Desktop.
#! /usr/bin/ruby -w
require 'rubygems'
require 'rmagick'
require 'fileutils'
include Magick
puts 'Go!'
limit = ARGV.length > 1 ? ARGV[1].to_i : 18
file = ARGV[0]
puts "Processing #{file} with depth of #{limit}"
# Check file exists
unless File::exists?( file )
puts "Image #{file} not found"
abort("Image #{file} not found")
end
#Setup
img_name = File.basename(file, ".jpg")
# Load the source image and a little information
img = Magick::Image.read(file).first
w = img.columns
h = img.rows
puts "Image #{file} too small (<512x512)" and abort('') unless (h > 512 || w > 512)
FileUtils.rm_rf(img_name) if File::directory?(img_name)
dir_name = img_name.split('.').slice(0,img_name.split('.').length - 1).to_s.gsub('["', '').gsub('"]', '');
puts dir_name;
Dir.mkdir(dir_name)
# Find the next largest multiple of 256 and the power of 2
dim = w > h ? w : h
pow = -1
loop do
i = 256*(2**pow+=1)
next if i < dim
dim = i
break
end
# Resize the source image up to the larger size
if (dim > w && dim > h)
puts "Resizing image to #{dim}px"
# Determine the optimal pixel radius for sharpening
img.change_geometry!("#{dim}x#{dim}") { |cols, rows, i|
i.resize!(cols, rows)
}
sharp = ( w/dim > h/dim ? dim/w : dim/h )/2
img = img.sharpen(sharp)
end
# Build a new square image with a black background, and composite the source image on top of it.
master = Magick::Image.new(dim,dim){ self.background_color = "transparent" }
master.composite!(img, Magick::CenterGravity, Magick::OverCompositeOp)
img = nil
# Create slice layers
layer = 0
loop do
# Google Maps only allows 19 layers (though I doubt we'll ever reach this point).
break if layer > limit
width = 256*(2**layer)
break if width > dim
Dir.mkdir("#{dir_name}/#{layer}", 0775) unless File::directory?("#{dir_name}/#{layer}")
crop_master = master.clone
crop_master.resize!(width, width)
max_loop = (width / 256) - 1
(0 .. max_loop).each do |x|
Dir.mkdir("#{dir_name}/#{layer}/#{x}", 0775) unless File::directory?("#{dir_name}/#{layer}/#{x}")
(0 .. max_loop).each do |y|
crop = crop_master.clone
crop.crop!( x*256, crop_master.rows - ((y + 1) * 256), 256, 256)
crop.write("#{dir_name}/#{layer}/#{x}/#{y}.jpg")
crop = nil
end
end
layer+=1
crop_master = nil
end
master = nil
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment