#!/usr/bin/python from __future__ import print_function import sys import gc import glob, os import shutil import hashlib import json from PIL import Image mirror_names = glob.glob("tiff/*-m.tif") for m in mirror_names: im = Image.open(m) im_mirrored = im.transpose(Image.FLIP_LEFT_RIGHT) im.save(m.replace("-m.tif", "-l.tif")) im_mirrored.save(m.replace("-m.tif", "-r.tif")) FROM_DPI = 1200 TO_DPI_2X = 2 * 80 RATIO_2X = float(TO_DPI_2X) / float(FROM_DPI) RATIO_1X = RATIO_2X / 2 def print_status(*args): print(*args, end=" ") sys.stdout.flush() def pixIn(b, p): g = 4 return (((b['x1']-g) < p[0]) and ((b['x2']+g) > p[0]) and ((b['y1']-g) < p[1]) and ((b['y2']+g) > p[1])) def boxCenter(b): return { "x": (b['x1']+b['x2'])/2 , "y": ((b['y1']+b['y2'])/2)-1 } def boxAdd(b, cx, cy): if b: b['x1'] = min(b['x1'], cx) b['x2'] = max(b['x2'], cx) b['y1'] = min(b['y1'], cy) b['y2'] = max(b['y2'], cy) else: b = {'x1': cx, 'x2': cx, 'y1':cy, 'y2': cy} return b def floodFill(im, pix, color, cx, cy, to_color=(0, 0, 0)): global b b = None global queue queue = [(cx, cy)] def visit((px, py)): global b global queue try: p = pix[px, py][:3] except IndexError: return if p == color: b = boxAdd(b, px, im.size[1] - py) pix[px, py] = to_color queue.append((px + 1, py)) queue.append((px - 1, py)) queue.append((px, py + 1)) queue.append((px, py - 1)) while queue: visit(queue.pop(0)) return b and boxCenter(b) if not os.path.exists("assets"): os.makedirs("assets") art_names = glob.glob("tiff/*.tif") sources_seen = 0 print("") print_status("| generating...") for in_name in art_names: sources_seen += 1 print_status(": [{} of {}]".format(sources_seen, len(art_names)), in_name, "|") print_status("h") with open(in_name, "r") as im_data: im_hash = hashlib.sha1(im_data.read()).hexdigest()[:16] print_status("l") im = Image.open(in_name) grip_name = os.path.join("assets", "{}.json".format(im_hash)) if os.path.exists(grip_name): print_status("=") else: print_status("g") root = [] attach = [] pix = im.load() for cx in range(im.size[0]): for cy in range(im.size[1]): p = pix[cx, cy][:3] if p == (255, 255, 0) or p == (0, 0, 255): # root to_color = (255, 255, 255, 0) if p[2] == 255 else (0, 0, 0, 255) root.append(floodFill(im, pix, p, cx, cy, to_color)) print_status("a") elif p == (255, 0, 0) or p == (0, 255, 0): # attach to_color = (255, 255, 255, 0) if p[1] == 255 else (0, 0, 0, 255) attach.append(floodFill(im, pix, p, cx, cy, to_color)) print_status("r") # scale points to 1x pixel density for points in (root, attach): for point in points: point["x"] = int(point["x"] * RATIO_1X) point["y"] = int(point["y"] * RATIO_1X) with open(grip_name, "w") as f: json.dump({"attach": attach, "root": root and root[0]}, f) fname = os.path.basename(in_name) fbarename = os.path.splitext(fname)[0] for ratio, prefix in ((RATIO_1X, ''), (RATIO_2X, '2x-')): resized_name = os.path.join("assets", "{}{}.png".format(prefix, fbarename)) print_status("r") im_resized = im.resize((int(im.size[0] * ratio), int(im.size[1] * ratio)), Image.ANTIALIAS) im_resized = im_resized.convert('RGBA') pix_resized = im_resized.load() # convert white to alpha for cx in range(im_resized.size[0]): for cy in range(im_resized.size[1]): p = pix_resized[cx, cy] pix_resized[cx, cy] = (0, 0, 0, 255 - (sum(p[:3]) / 3)) print_status("w") if im_resized.info.has_key("icc_profile"): del im_resized.info["icc_profile"] im_resized.save(resized_name, "PNG", optimize=True) print(".")