#!/usr/bin/env python from PIL import Image import re def fitbox (boxw, boxh, w, h): rw = boxw rh = int(rw * (float(h) / w)) if (rh >= boxh): rh = boxh rw = int(rh * (float(w) / h)) return rw, rh def tile_image (im, maxz=0, tilew=256, tileh=256, base=".", template="z{0[z]}y{0[y]}x{0[x]}.jpg", bgcolor=(0,0,0), margin_right=0, margin_bottom=0): z = 0 boxw, boxh = tilew, tileh alpha = bgcolor != None # not template.endswith("jpg") while True: rw, rh = fitbox(boxw, boxh, im.size[0], im.size[1]) rim = im.resize((rw-margin_right, rh-margin_bottom), Image.ANTIALIAS) if bgcolor: tim = Image.new("RGB", (boxw, boxh), bgcolor) tim.paste(rim, (0, 0)) else: tim = Image.new("RGBA", (boxw, boxh)) tim.paste(rim, (0, 0)) rows, cols = 2**z, 2**z for r in range(rows): for c in range(cols): ix = c*tileh iy = r*tilew cim = tim.crop((ix, iy, ix+tilew, iy+tileh)) op = base + template.format({'z':z, 'x':c, 'y':r}) # if not alpha: # cim = cim.convert("RGB") cim.save(op) z += 1 if z>maxz: break boxw *= 2 boxh *= 2 if __name__ == "__main__": from argparse import ArgumentParser p = ArgumentParser("tile an image") p.add_argument("--tilewidth", type=int, default=256, help="default: 256") p.add_argument("--tileheight", type=int, default=256, help="default: 256") p.add_argument("input") p.add_argument("--output", default="./tile", help="output path, default: ./tile") p.add_argument("--tilename", default="Z{z}Y{y}X{x}.jpg", help="template for tiles, default: Z{z}Y{y}X{x}.jpg") p.add_argument("--background", default="0,0,0", help="background color, default: 0,0,0") p.add_argument("--zoom", type=int, default=0, help="default 0") args = p.parse_args() im = Image.open(args.input) tilename = re.sub(r"\{(.+?)\}", r"{0[\1]}", args.tilename) background = tuple([int(x) for x in args.background.split(",")]) tile_image (im, args.zoom, args.tilewidth, args.tileheight, args.output, tilename, background)