-
-
Save akanieski/a05e961e7f262765f1e4 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#! /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