tiles.py 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. import os
  2. from math import sqrt, log10, ceil
  3. import logging
  4. from PIL import Image
  5. from path import path
  6. log = logging.getLogger()
  7. def createLog2Tiles(inputFile, output_dir, logger=None, tilesize=256, rgba=False):
  8. if logger is not None:
  9. log = logger
  10. im = Image.open(inputFile)
  11. xsize, ysize = im.size
  12. log2 = lambda x: log10(x) / log10(2) # log2 (base 2 logarithm)
  13. maxzoom = int(max(ceil(log2(xsize / float(tilesize))), ceil(log2(ysize / float(tilesize)))))
  14. zoompixels = [2.0 ** (maxzoom - zoom) for zoom in range(0, maxzoom + 1)]
  15. tilecount = sum([
  16. int(ceil(xsize / (2.0 ** (maxzoom - zoom) * tilesize))) * \
  17. int(ceil(ysize / (2.0 ** (maxzoom - zoom) * tilesize))) \
  18. for zoom in range(maxzoom + 1)
  19. ])
  20. # Create output directory, if it doesn't exist
  21. if not os.path.isdir(output_dir):
  22. os.makedirs(output_dir)
  23. log.info("Output (%s):" % output_dir)
  24. log.info("Format of tiles: png")
  25. log.info("Size of a tile: %s x %s pixels " % (tilesize, tilesize))
  26. log.info("Count of tiles: %s" % tilecount)
  27. log.info("Zoom levels of the pyramid: %s" % maxzoom)
  28. log.info("Pixel resolution by zoomlevels: %s" % zoompixels)
  29. tileno = 0
  30. progress = 0
  31. for zoom in range(maxzoom, -1, -1):
  32. # Maximal size of read window in pixels.
  33. rmaxsize = 2.0 ** (maxzoom - zoom) * tilesize
  34. log.debug("-"*80)
  35. log.debug("Zoom %s - pixel %.20f %s" % (zoom, zoompixels[zoom], int(2.0 ** zoom * tilesize)))
  36. log.debug("-"*80)
  37. for ix in range(0, int(ceil(xsize / rmaxsize))):
  38. # Read window xsize in pixels.
  39. if ix + 1 == int(ceil(xsize / rmaxsize)) and xsize % rmaxsize != 0:
  40. rxsize = int(xsize % rmaxsize)
  41. else:
  42. rxsize = int(rmaxsize)
  43. # Read window left coordinate in pixels.
  44. rx = int(ix * rmaxsize)
  45. for iy in range(0, int(ceil(ysize / rmaxsize))):
  46. # Read window ysize in pixels.
  47. if iy + 1 == int(ceil(ysize / rmaxsize)) and ysize % rmaxsize != 0:
  48. rysize = int(ysize % rmaxsize)
  49. else:
  50. rysize = int(rmaxsize)
  51. # Read window top coordinate in pixels.
  52. ry = int(ysize - (iy * rmaxsize)) - rysize
  53. dxsize = int(rxsize / rmaxsize * tilesize)
  54. dysize = int(rysize / rmaxsize * tilesize)
  55. if rgba:
  56. filename = path(output_dir).joinpath(str(zoom), str(ix), str(iy) + '.png')
  57. else:
  58. filename = path(output_dir).joinpath(str(zoom), str(ix), str(iy) + '.jpg')
  59. if not filename.parent.exists():
  60. filename.parent.makedirs()
  61. # Print info about tile and read area.
  62. croppedIm = im.crop([rx,ry,rx+rxsize,ry+rysize])
  63. croppedIm = croppedIm.resize((dxsize,dysize),resample=Image.ANTIALIAS) #Choices: NONE,NEAREST,ANTIALIAS,BILINEAR,BICUBIC
  64. if (rxsize, rysize) != (dxsize, dysize):
  65. if rgba:
  66. newImage = Image.new('RGBA', (tilesize, tilesize), (0, 0, 0, 0))
  67. else:
  68. newImage = Image.new('RGB', (tilesize, tilesize), 'white')
  69. newImage.paste(croppedIm, (0, tilesize - dysize))
  70. croppedIm = newImage
  71. croppedIm.save(filename,**{'quality':50})
  72. tileno += 1
  73. if __name__ == '__main__':
  74. createLog2Tiles(r't:\xx.png', 'r:/floor1')