gen_tiles.py 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. # -*- coding: utf-8 -*-
  2. """
  3. Given an image, generate a set of tiles at various zoom levels.
  4. The format of the filename of times is:
  5. 00<zoom>-00<x>-00<y>.jpg
  6. where zoom is 0 for the original size, 1 when the image is downscaled 2
  7. times, 2 when the image is downscaled 4 times, etc.
  8. """
  9. from __future__ import unicode_literals, division, print_function
  10. import sys
  11. import os
  12. import tempfile
  13. import PIL.Image
  14. from PIL import ImageDraw
  15. def gen_tiles(image, output_path, min_scale=0, max_scale=8, crop_x=256, crop_y=256):
  16. orig_im = PIL.Image.open(image)
  17. for scale in range(min_scale, max_scale + 1):
  18. if scale == 0:
  19. im = orig_im
  20. scaled_size = im.size
  21. else:
  22. scaled_size = (orig_im.size[0] >> scale, orig_im.size[1] >> scale)
  23. im = orig_im.resize(scaled_size, resample=PIL.Image.BILINEAR)
  24. # Compute a size that is a multiple of the tile size
  25. rounded_size = (crop_x + crop_x * ((im.size[0] - 1) // crop_x),
  26. crop_y + crop_y * ((im.size[1] - 1) // crop_y))
  27. if rounded_size != scaled_size:
  28. im = im.transform(rounded_size, PIL.Image.AFFINE, (1, 0, 0, 0, 1, 0))
  29. if False and rounded_size[0] != scaled_size[0]: # TODO: check if 360 or not
  30. # Repeat the same image horizontally
  31. print((scale, 0, 0, rounded_size[0] - scaled_size[0], scaled_size[1]))
  32. print((scale, scaled_size[0], 0, rounded_size[0], scaled_size[1]))
  33. cropped = im.crop((0, 0, rounded_size[0] - scaled_size[0], scaled_size[1]))
  34. im.paste(cropped, (scaled_size[0], 0, rounded_size[0], scaled_size[1]))
  35. for x in range(0, im.size[0], crop_x):
  36. for y in range(0, im.size[1], crop_y):
  37. geom = (x, y, min(im.size[0], x + crop_x), min(im.size[1], y + crop_y))
  38. dest = os.path.join(output_path,
  39. "{}-{}-{}.jpg".format(-scale,
  40. x // crop_x,
  41. y // crop_y))
  42. tile = im.crop(geom)
  43. #draw = ImageDraw.Draw(tile)
  44. #draw.line((0, 0, 0, 255), width=2, fill="red")
  45. #draw.line((0, 255, 255, 255), width=2, fill="red")
  46. #draw.line((255, 255, 255, 0), width=2, fill="red")
  47. #draw.line((255, 0, 0, 0), width=2, fill="red")
  48. tile.save(dest)
  49. if __name__ == '__main__':
  50. if len(sys.argv) < 2:
  51. print("Usage: {} <image>".format(sys.argv[0]))
  52. print("Generate tiles of the given image.")
  53. exit(1)
  54. origin = sys.argv[1]
  55. out = tempfile.mkdtemp(prefix="demo-pano-")
  56. print("Generating tiles in {} ...".format(out))
  57. gen_tiles(origin, out)