Skip to content

Instantly share code, notes, and snippets.

@numinit
Created September 24, 2017 21:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save numinit/b6df1c7a247f143339e0cf9caa8df414 to your computer and use it in GitHub Desktop.
Save numinit/b6df1c7a247f143339e0cf9caa8df414 to your computer and use it in GitHub Desktop.
from PIL import Image
import sys
def maskify(filename):
im = Image.open(filename)
px = im.load()
width, height = im.size
stride = 32
rows = []
for y in range(height):
row = []
for x in range(0, width, stride):
word = 0
for i in range(stride):
coord = (x + i, y)
if coord[0] >= width:
break
else:
pixel = px[coord[0], coord[1]]
if pixel > 0:
word |= (1 << i)
row.append(word)
rows.append(row)
return rows
def img2webgl(rows, u, v, width, height):
boilerplate = """
#define TOP_U {top_u}
#define TOP_V {top_v}
#define BOTTOM_U {bottom_u}
#define BOTTOM_V {bottom_v}
#define NUM_ROWS {num_rows}
#define NUM_COLS {num_cols}
const uint[NUM_ROWS * NUM_COLS] bitmap = uint[] (
{rows}
);
vec4 render_bitmap(in vec2 originalUv, in vec4 pixel) {{
vec2 uv = vec2(originalUv.x, 1. - originalUv.y);
if (uv.x < TOP_U || uv.x > BOTTOM_U ||
uv.y < TOP_V || uv.y > BOTTOM_V) {{
// Not in the u/v box.
return pixel;
}}
// Pick a pixel to sample
float x_fraction = (uv.x - TOP_U) / (BOTTOM_U - TOP_U);
float y_fraction = (uv.y - TOP_V) / (BOTTOM_V - TOP_V);
// Quantize to the nearest bitmap pixel
uint x_off = uint(trunc(x_fraction * float(NUM_COLS * 32)));
uint x_bit = x_off & 0x1fU;
x_off >>= 5;
uint y_off = uint(trunc(y_fraction * float(NUM_ROWS)));
float color = float(
(bitmap[y_off * uint(NUM_COLS) + x_off] & (1U << x_bit)) >> x_bit
);
return mix(pixel, vec4(color, color, color, 1.), color);
}}
""".strip()
statements = []
for row_idx, row in enumerate(rows):
formatted_row = []
for col_idx, col in enumerate(row):
formatted_row.append('0x%08xU' % col)
statements.append(' %s' % ', '.join(formatted_row))
return boilerplate.format(
top_u='%.8f' % u,
top_v='%.8f' % v,
bottom_u='%.8f' % (u + width),
bottom_v='%.8f' % (v + height),
num_rows=len(rows),
num_cols=len(rows[0]),
rows=",\n".join(statements)
)
if len(sys.argv) != 6:
raise ValueError(
'Usage: %s <input PNG> <top left U coord> <top left V coord> ' +
'<fraction width> <fraction height>'
)
print(img2webgl(maskify(sys.argv[1]), float(sys.argv[2]), float(sys.argv[3]),
float(sys.argv[4]), float(sys.argv[5])))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment