Advertisement
AndreasBWagner

create_tiles.pl for leafletjs

Oct 16th, 2013
166
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Perl 5.11 KB | None | 0 0
  1. #!/usr/bin/perl -w
  2. #
  3. # vim:ts=4:sw=4:ai:et:si:sts=4:sta
  4. #
  5. # Copyright 2008 Chris Petersen and iFloor.com
  6. #
  7. # This application is distributed under the GNU Lesser GPL version 2 or later:
  8. # http://www.gnu.org/licenses/lgpl.html
  9. #
  10.  
  11. =head1 create_tiles.pl
  12.  
  13. Export tiles for use with Google Maps API for image zoom.
  14.  
  15. This breaks up an image into "zoom" tiles that can be used as a custom map
  16. type, as described here:
  17.  
  18.   http://code.google.com/apis/maps/documentation/overlays.html#Custom_Map_Types
  19.  
  20. =cut
  21.  
  22. use strict;
  23. use Carp;
  24.  
  25. use File::Path;
  26. use File::Basename;
  27. use Getopt::Long;
  28. use Image::Magick;
  29.  
  30. ###############################################################################
  31. # Initialization
  32. #
  33.  
  34. # Arg variables
  35.     my ($path, $verbose, $help);
  36.  
  37. # CLI args
  38.     GetOptions(
  39.         'path=s'    => \$path,
  40.         'verbose'   => \$verbose,
  41.         'help'      => \$help,
  42.         );
  43.  
  44.     if ($help || @ARGV < 1) {
  45.         print STDERR "usage $0 [-v] [--path /tmp/tiles] img [, img2, img3, ...]\n";
  46.         exit;
  47.     }
  48.  
  49. # Defaults
  50.     $path ||= '.';
  51.  
  52. ###############################################################################
  53. # Code
  54. #
  55.  
  56.     my %seen;
  57.     foreach my $img_path (@ARGV) {
  58.     # Duplicate detection/avoidance
  59.         next if ($seen{$img_path});
  60.         $seen{$img_path} = 1;
  61.     # Skip?
  62.         unless (-e $img_path) {
  63.             print STDERR "$img_path does not exist.\n";
  64.             next;
  65.         }
  66.     # Setup
  67.         print "Create Tiles:  $img_path\n" if ($verbose);
  68.         my $tile_dir = "$path/".basename($img_path);
  69.         $tile_dir =~ s/\.\w+$//;
  70.     # Delete any old instances of the tile directory
  71.         rmtree($tile_dir);
  72.     # Load the source image and a little information
  73.         my $img = Image::Magick->new;
  74.         $img->Read($img_path);
  75.         my $w   = $img->Get('width');
  76.         my $h   = $img->Get('height');
  77. print "$w $h\n";
  78.     # Too small to zoom?
  79.         next unless ($h > 512 || $w > 512);
  80.     # (Re)create the target directory
  81.         my $ubak = umask(0);
  82.         mkpath($tile_dir, 0, 0755);
  83.         umask($ubak);
  84.     # Find the next largest multiple of 256 and the power of 2
  85.         my $dim = ($w > $h ? $w : $h);
  86.         my $pow = -1;
  87.         for (;;) {
  88.             $pow++;
  89.             my $i = 256 * (2 ** $pow);
  90.             next if ($i < $dim);
  91.             $dim = $i;
  92.             last;
  93.         }
  94.     # Resize the source image up to the larger size, so the zoomed-out images
  95.     # get as little of the black padding/background as possible.  Hopefully it
  96.     # won't distort the images too badly.
  97.         if ($dim > $w && $dim > $h) {
  98.         # Determine the optimal pixel radius for sharpening, and do so
  99.             my $sharp = ($w / $dim > $h / $dim
  100.                 ? $dim / $w
  101.                 : $dim / $h
  102.                 ) / 2;
  103.             $img->Sharpen(radius => $sharp);
  104.         # Resize
  105.         $img->Resize(geometry => "${dim}x$dim"); #Changed
  106.         }
  107.     # Build a new square image with a black background, and composite the
  108.     # source image on top of it.
  109.         my $master = Image::Magick->new;
  110.         $master->Set('size' => "${dim}x$dim");
  111.         $master->Read("xc:white");
  112.         $master->Composite(
  113.             'image'   => $img,
  114.             'gravity' => 'Center',# Changed
  115.             );
  116.     # Cleanup
  117.         undef $img;
  118.     # Create slice layers
  119.         my $layer = 0;
  120.         for (;;) {
  121.             # Google Maps only allows 19 layers (though I doubt we'll ever
  122.             # reach this point).
  123.             last if ($layer >= 19);
  124.  
  125.             my $width = 256 * (2 ** $layer);
  126.             last if ($width > $dim);
  127.  
  128.             mkdir("$tile_dir/$layer", 0775) unless (-d "$tile_dir/$layer");
  129.  
  130.             my $crop_master = $master->Clone();
  131.             $crop_master->Blur(radius => ($dim / $width) / 2);
  132.             $crop_master->Resize(
  133.                 geometry => "${width}x$width",
  134.                 blur     => .7,
  135.                 );
  136.             my $max_loop = int($width / 256) - 1;
  137.  
  138.             if ($verbose) {
  139.                 my $num_tiles = ($max_loop+1) ** 2;
  140.                 print "  Layer $layer ($num_tiles tile",
  141.                       ($num_tiles == 1 ? '' : 's'),
  142.                       ")\n";
  143.             }
  144.  
  145.             foreach my $x (0 .. $max_loop) {
  146.                 foreach my $y (0 .. $max_loop) {
  147.                     my $crop = $crop_master->Clone();
  148.                     $crop->Crop(
  149.                         height => 256,
  150.                         width  => 256,
  151.                         x      => $x * 256,
  152.                         y      => $y * 256,
  153.                         );
  154.                     $crop->Write(
  155.                         filename => "$tile_dir/$layer/$x-$y.png",
  156.                         quality  => 75,
  157.                         );
  158.                     $ubak = umask(0);
  159.                     chmod 0644, "$tile_dir/$layer/$x-$y.png";
  160.                     umask($ubak);
  161.                     undef $crop;
  162.                 }
  163.             }
  164.             $layer++;
  165.         # Cleanup
  166.             undef $crop_master;
  167.         }
  168.     # Cleanup
  169.         undef $master;
  170.     }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement