Skip to content

Instantly share code, notes, and snippets.

@spdral
Created April 14, 2023 21:29
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 spdral/0afee5917714bf01d4e647a3822d1c77 to your computer and use it in GitHub Desktop.
Save spdral/0afee5917714bf01d4e647a3822d1c77 to your computer and use it in GitHub Desktop.
cmelevator
import PIL.Image
import numpy as np
def remove_buildings(clean: np.ndarray, elevated: np.ndarray) -> np.ndarray:
xorred = np.bitwise_xor(clean, elevated)
output = xorred
return output
def load_image(path: str) -> np.ndarray:
image = PIL.Image.open(path).convert("RGB")
array = np.array(image)
mask = np.all(array == [255, 255, 255], axis=2)
output = np.zeros_like(array)
output[mask] = [255, 255, 255]
return output
def load_font() -> list[np.ndarray]:
# the image is 50x7
font = load_image("./font.png")
return [font[0:7, l:r] for l, r in zip(range(0, 46, 5), range(5, 51, 5))]
def match(tile: np.ndarray, font: list[np.ndarray]) -> int:
# white_glyph = np.full((7, 5, 3), [255, 255, 255], np.uint8)
glyph_shape = (7, 5, 3)
for i in range(len(font)):
glyph = font[i]
compared = np.bitwise_and(
glyph, tile[4 : 4 + glyph_shape[0], 5 : 5 + glyph_shape[1]]
)
match = np.all(compared == glyph)
if match:
return i
ones = None
tens = None
for i in range(len(font)):
glyph = font[i]
l = np.bitwise_and(glyph, tile[4 : 4 + glyph_shape[0], 2 : 2 + glyph_shape[1]])
r = np.bitwise_and(glyph, tile[4 : 4 + glyph_shape[0], 8 : 8 + glyph_shape[1]])
l_match = np.all(l == glyph)
r_match = np.all(r == glyph)
if l_match:
tens = i
if r_match:
ones = i
if None not in [tens, ones]:
value = int(f"{tens}{ones}")
return value
return 255
if __name__ == "__main__":
clean = load_image("./tile-clean.png")
elevated = load_image("./tile-elevation.png")
font = load_font()
tile_x = 16
tile_y = 16
m = load_image("./map-elevation.png")
y_dim = m.shape[0] // tile_y
x_dim = m.shape[1] // tile_x
elevations = np.full(m.shape[:2], 255, np.uint8)
for y in range(y_dim):
for x in range(x_dim):
y_start = y * tile_y
y_stop = y_start + tile_y
x_start = x * tile_x
x_stop = x_start + tile_x
tile = m[y_start:y_stop, x_start:x_stop]
value = match(tile, font)
elevations[y][x] = value
lowest = np.min(elevations)
cond_list = [elevations < 255]
choice_list = [elevations]
elevations = np.select(cond_list, choice_list, 0)
highest = np.max(elevations)
top = highest - lowest
output = np.zeros(m.shape, np.uint8)
for y in range(y_dim):
for x in range(x_dim):
y_start = y * tile_y
y_stop = y_start + tile_y
x_start = x * tile_x
x_stop = x_start + tile_x
value = elevations[y][x]
if value > 0:
color = [255 // top * value] * 3
else:
color = [0, 0, 0]
output[y_start:y_stop, x_start:x_stop] = color
print(lowest, highest, top)
print(*output.shape)
output = PIL.Image.fromarray(output, mode="RGB")
output.save("./tile-no-buildings.png")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment