Created
September 24, 2017 21:59
-
-
Save numinit/b6df1c7a247f143339e0cf9caa8df414 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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