import os from math import sqrt, log10, ceil import logging from PIL import Image from path import path log = logging.getLogger() def createLog2Tiles(inputFile, output_dir, logger=None, tilesize=256, rgba=False): if logger is not None: log = logger im = Image.open(inputFile) xsize, ysize = im.size log2 = lambda x: log10(x) / log10(2) # log2 (base 2 logarithm) maxzoom = int(max(ceil(log2(xsize / float(tilesize))), ceil(log2(ysize / float(tilesize))))) zoompixels = [2.0 ** (maxzoom - zoom) for zoom in range(0, maxzoom + 1)] tilecount = sum([ int(ceil(xsize / (2.0 ** (maxzoom - zoom) * tilesize))) * \ int(ceil(ysize / (2.0 ** (maxzoom - zoom) * tilesize))) \ for zoom in range(maxzoom + 1) ]) # Create output directory, if it doesn't exist if not os.path.isdir(output_dir): os.makedirs(output_dir) log.info("Output (%s):" % output_dir) log.info("Format of tiles: png") log.info("Size of a tile: %s x %s pixels " % (tilesize, tilesize)) log.info("Count of tiles: %s" % tilecount) log.info("Zoom levels of the pyramid: %s" % maxzoom) log.info("Pixel resolution by zoomlevels: %s" % zoompixels) tileno = 0 progress = 0 for zoom in range(maxzoom, -1, -1): # Maximal size of read window in pixels. rmaxsize = 2.0 ** (maxzoom - zoom) * tilesize log.debug("-"*80) log.debug("Zoom %s - pixel %.20f %s" % (zoom, zoompixels[zoom], int(2.0 ** zoom * tilesize))) log.debug("-"*80) for ix in range(0, int(ceil(xsize / rmaxsize))): # Read window xsize in pixels. if ix + 1 == int(ceil(xsize / rmaxsize)) and xsize % rmaxsize != 0: rxsize = int(xsize % rmaxsize) else: rxsize = int(rmaxsize) # Read window left coordinate in pixels. rx = int(ix * rmaxsize) for iy in range(0, int(ceil(ysize / rmaxsize))): # Read window ysize in pixels. if iy + 1 == int(ceil(ysize / rmaxsize)) and ysize % rmaxsize != 0: rysize = int(ysize % rmaxsize) else: rysize = int(rmaxsize) # Read window top coordinate in pixels. ry = int(ysize - (iy * rmaxsize)) - rysize dxsize = int(rxsize / rmaxsize * tilesize) dysize = int(rysize / rmaxsize * tilesize) if rgba: filename = path(output_dir).joinpath(str(zoom), str(ix), str(iy) + '.png') else: filename = path(output_dir).joinpath(str(zoom), str(ix), str(iy) + '.jpg') if not filename.parent.exists(): filename.parent.makedirs() # Print info about tile and read area. croppedIm = im.crop([rx,ry,rx+rxsize,ry+rysize]) croppedIm = croppedIm.resize((dxsize,dysize),resample=Image.ANTIALIAS) #Choices: NONE,NEAREST,ANTIALIAS,BILINEAR,BICUBIC if (rxsize, rysize) != (dxsize, dysize): if rgba: newImage = Image.new('RGBA', (tilesize, tilesize), (0, 0, 0, 0)) else: newImage = Image.new('RGB', (tilesize, tilesize), 'white') newImage.paste(croppedIm, (0, tilesize - dysize)) croppedIm = newImage croppedIm.save(filename,**{'quality':50}) tileno += 1 if __name__ == '__main__': createLog2Tiles(r't:\xx.png', 'r:/floor1')