packages feed

linden-0: extract_grips.py

#!/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(".")