# Grouper: zooms of the user's blueprint with pixel rulers in ORIGINAL image coordinates (plain Python: PIL, numpy). # python gr_zoom.py -> reference/z4_*.png (the standard tiles) # python gr_zoom.py name x0 y0 x1 y1 [k] -> reference/z4_.png (any box) # Rulers: a tick every 5 px, a label every 10 px (original pixels); a faint red grid every 10 px, stronger every 50. import sys, os from PIL import Image, ImageDraw, ImageFont HERE = os.path.dirname(os.path.abspath(__file__)) REF = os.path.normpath(os.path.join(HERE, "..", "reference")) SRC = os.path.join(REF, "user_blueprint.jpg") TILES = { # SIDE: body x 505..965, y 258..485 "side_aft": (500, 258, 670, 488, 4), "side_mid": (660, 258, 830, 488, 4), "side_fore": (820, 258, 990, 488, 4), # TOP: body x 505..965, y 45..240 "top_aft": (500, 40, 670, 242, 4), "top_mid": (660, 40, 830, 242, 4), "top_fore": (820, 40, 990, 242, 4), # BOTTOM "bot_aft": (500, 520, 670, 722, 4), "bot_mid": (660, 520, 830, 722, 4), "bot_fore": (820, 520, 990, 722, 4), # FRONT, BACK, the two sections "front": (140, 255, 320, 485, 4), "back": (1110, 260, 1300, 480, 4), "secA_tr": (1125, 25, 1290, 205, 4), "secA_bl": (150, 565, 315, 710, 4), } def zoom(name, x0, y0, x1, y1, k=4, src=SRC, out=None): im = Image.open(src).convert("RGB").crop((x0, y0, x1, y1)) w, h = im.size im = im.resize((w * k, h * k), Image.LANCZOS) M = 34 # margin for the rulers can = Image.new("RGB", (w * k + 2 * M, h * k + 2 * M), (255, 255, 255)) can.paste(im, (M, M)) ov = Image.new("RGBA", can.size, (0, 0, 0, 0)) d = ImageDraw.Draw(ov) try: f = ImageFont.truetype("arial.ttf", 11) except Exception: f = ImageFont.load_default() for x in range(x0 - x0 % 5, x1 + 1, 5): if x < x0: continue X = M + (x - x0) * k major = x % 10 == 0 if major: d.line([(X, M), (X, M + h * k)], fill=(255, 40, 40, 140 if x % 50 == 0 else 55), width=1) for Y0, Y1 in ((M - (10 if major else 5), M), (M + h * k, M + h * k + (10 if major else 5))): d.line([(X, Y0), (X, Y1)], fill=(0, 0, 0, 255), width=1) if major: d.text((X - 10, 2), str(x), fill=(0, 0, 0, 255), font=f) d.text((X - 10, M + h * k + 12), str(x), fill=(0, 0, 0, 255), font=f) for y in range(y0 - y0 % 5, y1 + 1, 5): if y < y0: continue Y = M + (y - y0) * k major = y % 10 == 0 if major: d.line([(M, Y), (M + w * k, Y)], fill=(255, 40, 40, 140 if y % 50 == 0 else 55), width=1) for X0, X1 in ((M - (10 if major else 5), M), (M + w * k, M + w * k + (10 if major else 5))): d.line([(X0, Y), (X1, Y)], fill=(0, 0, 0, 255), width=1) if major: d.text((1, Y - 6), str(y), fill=(0, 0, 0, 255), font=f) d.text((M + w * k + 3, Y - 6), str(y), fill=(0, 0, 0, 255), font=f) can = Image.alpha_composite(can.convert("RGBA"), ov).convert("RGB") out = out or os.path.join(REF, "z4_%s.png" % name) can.save(out) return out if __name__ == "__main__": if len(sys.argv) >= 6: n = sys.argv[1] x0, y0, x1, y1 = map(int, sys.argv[2:6]) k = int(sys.argv[6]) if len(sys.argv) > 6 else 4 print(zoom(n, x0, y0, x1, y1, k)) else: for n, (x0, y0, x1, y1, k) in TILES.items(): print(zoom(n, x0, y0, x1, y1, k))