Created
April 9, 2013 15:20
Revisions
-
mattolson created this gist
Apr 9, 2013 .There are no files selected for viewing
This file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,130 @@ #!/usr/bin/env ruby require 'rubygems' require 'fileutils' require 'open-uri' require 'rexml/document' require 'tempfile' require 'shellwords' module Shell # Exceptions class CommandFailed < RuntimeError; end def run(command, args="") full_command = "#{command} #{escape_args(args)}" puts "Running command: #{full_command}" begin result = `#{full_command}` rescue Errno::ENOENT raise_shell_command_failed(full_command) end if $?.exitstatus == 1 throw :unable_to_handle elsif !$?.success? raise_shell_command_failed(full_command) end end def raise_shell_command_failed(command) raise CommandFailed, "Command failed (#{command}) with exit status #{$?.exitstatus}" end def escape_args(args) args.shellsplit.map do |arg| quote arg.gsub(/\\?'/, %q('\\\\'')) end.join(' ') end def quote(s) "'#{s}'" end end class Zoomify TILESIZE = 256 include Shell def unzoomify(url, level=5) @url = url @level = level @output_filename = "tmp/#{File.basename(@url)}.png" # Read properties file doc = nil begin open("#{@url}/ImageProperties.xml") do |f| doc = REXML::Document.new(f) end rescue OpenURI::HTTPError puts "ERROR: Failed to open ImageProperties.xml" return nil end # Sanity check attrs = doc.root.attributes unless attrs['TILESIZE'] == TILESIZE.to_s && attrs['VERSION'] == '1.8' puts "ERROR: unexpected tile size" return nil end # Get properties width = attrs['WIDTH'].to_i height = attrs['HEIGHT'].to_i num_tiles = attrs['NUMTILES'].to_i num_tiles_x = width / TILESIZE num_tiles_y = height / TILESIZE @tile_groups = (0..num_tiles/TILESIZE).to_a image = transparent(width, height) (0..num_tiles_x).each do |column| (0..num_tiles_y).each do |row| # Get tile filename = "#{@level}-#{column}-#{row}.jpg" puts "Getting #{filename}..." tile_image = get_tile(filename) # Merge it into master image composite!(tile_image, column*TILESIZE, row*TILESIZE) if tile_image end end return @output_filename end def get_tile(filename) @tile_groups.each do |group| begin tile_url = "#{@url}/TileGroup#{group}/#{filename}" file_ext = ".#{File.extname(filename).split('.').last}" tempfile = ::Tempfile.new ['unzoomify', file_ext] tempfile.binmode puts "Getting #{tile_url}..." open(tile_url) do |f| tempfile.write(f.read) end tempfile.close return tempfile rescue OpenURI::HTTPError, Errno::ENOENT puts "Not found." end end puts "WARNING: (#{@url}, #{filename}) appears to be missing or invalid" nil end def transparent(width, height) run :convert, %(-size #{width}x#{height} canvas:none #{@output_filename}) end def composite!(tile, x, y) run :composite, %(-compose src-over -geometry '#{TILESIZE}x#{TILESIZE}+#{x}+#{y}' #{tile.path} #{@output_filename} #{@output_filename}) end end z = Zoomify.new full_image_path = z.unzoomify 'directory_or_url' puts full_image_path ? "Full size image written to #{full_image_path}." : "ERROR"