|
|
from json.decoder import JSONDecodeError |
|
|
from PIL import Image, ImageDraw |
|
|
from json import loads |
|
|
|
|
|
DEFAULT_MAPPING = [["0.00:0.50", "0.00:1.00", "1.0"], ["0.50:1.00", "0.00:1.00", "1.0"]] |
|
|
COLORS = ("red", "orange", "yellow", "green", "blue", "indigo", "violet") |
|
|
|
|
|
|
|
|
def parse_mapping(data: list) -> list: |
|
|
mapping = [] |
|
|
|
|
|
for [X, Y, W] in data: |
|
|
if not X.strip(): |
|
|
continue |
|
|
|
|
|
mapping.append( |
|
|
( |
|
|
(float(X.split(":")[0]), float(X.split(":")[1])), |
|
|
(float(Y.split(":")[0]), float(Y.split(":")[1])), |
|
|
float(W), |
|
|
) |
|
|
) |
|
|
|
|
|
return mapping |
|
|
|
|
|
|
|
|
def validate_mapping(data: list) -> bool: |
|
|
try: |
|
|
for [X, Y, W] in data: |
|
|
if not X.strip(): |
|
|
continue |
|
|
|
|
|
assert len(X.split(":")) == 2 |
|
|
assert len(Y.split(":")) == 2 |
|
|
|
|
|
val = [] |
|
|
|
|
|
val.append(float(X.split(":")[0])) |
|
|
val.append(float(X.split(":")[1])) |
|
|
val.append(float(Y.split(":")[0])) |
|
|
val.append(float(Y.split(":")[1])) |
|
|
float(W) |
|
|
|
|
|
for v in val: |
|
|
if v < 0.0 or v > 1.0: |
|
|
raise OverflowError |
|
|
|
|
|
if val[1] < val[0] or val[3] < val[2]: |
|
|
raise IndexError |
|
|
|
|
|
return True |
|
|
|
|
|
except AssertionError: |
|
|
print("\n\n[Couple] Incorrect number of : in Mapping...\n\n") |
|
|
return False |
|
|
except ValueError: |
|
|
print("\n\n[Couple] Non-Number in Mapping...\n\n") |
|
|
return False |
|
|
except OverflowError: |
|
|
print("\n\n[Couple] Range must be between 0.0 and 1.0...\n\n") |
|
|
return False |
|
|
except IndexError: |
|
|
print('\n\n[Couple] "to" value must be larger than "from" value...\n\n') |
|
|
return False |
|
|
|
|
|
|
|
|
def visualize_mapping(res: str, data: list) -> Image: |
|
|
w, h = res.split("x") |
|
|
p_WIDTH = int(w) |
|
|
p_HEIGHT = int(h) |
|
|
|
|
|
while p_WIDTH > 1024 or p_HEIGHT > 1024: |
|
|
p_WIDTH //= 2 |
|
|
p_HEIGHT //= 2 |
|
|
|
|
|
while p_WIDTH < 512 and p_HEIGHT < 512: |
|
|
p_WIDTH *= 2 |
|
|
p_HEIGHT *= 2 |
|
|
|
|
|
matt = Image.new("RGBA", (p_WIDTH, p_HEIGHT), (0, 0, 0, 64)) |
|
|
|
|
|
if not (validate_mapping(data)): |
|
|
return matt |
|
|
|
|
|
lnw = int(max(min(p_WIDTH, p_HEIGHT) / 128, 4.0)) |
|
|
|
|
|
draw = ImageDraw.Draw(matt) |
|
|
|
|
|
mapping = parse_mapping(data) |
|
|
|
|
|
|
|
|
for tile_index in range(len(mapping)): |
|
|
color_index = tile_index % len(COLORS) |
|
|
|
|
|
(X, Y, W) = mapping[tile_index] |
|
|
x_from = int(p_WIDTH * X[0]) |
|
|
x_to = int(p_WIDTH * X[1]) |
|
|
y_from = int(p_HEIGHT * Y[0]) |
|
|
y_to = int(p_HEIGHT * Y[1]) |
|
|
|
|
|
|
|
|
|
|
|
draw.rectangle( |
|
|
((x_from, y_from), (x_to, y_to)), outline=COLORS[color_index], width=lnw |
|
|
) |
|
|
|
|
|
return matt |
|
|
|
|
|
|
|
|
def reset_mapping() -> list: |
|
|
return DEFAULT_MAPPING |
|
|
|
|
|
|
|
|
def add_row_above(data: list, index: int) -> list: |
|
|
if index < 0: |
|
|
return data |
|
|
return data[:index] + [["0.00:1.00", "0.00:1.00", "1.0"]] + data[index:] |
|
|
|
|
|
|
|
|
def add_row_below(data: list, index: int = None) -> list: |
|
|
if index is None or index < 0: |
|
|
return data + [["0.25:0.75", "0.25:0.75", "1.0"]] |
|
|
return data[: index + 1] + [["0.25:0.75", "0.25:0.75", "1.0"]] + data[index + 1 :] |
|
|
|
|
|
|
|
|
def del_row_select(data: list, index: int) -> list: |
|
|
if index < 0: |
|
|
return data |
|
|
if len(data) == 1: |
|
|
return [["0.0:1.0", "0.0:1.0", "1.0"]] |
|
|
else: |
|
|
del data[index] |
|
|
return data |
|
|
|
|
|
|
|
|
def on_paste(data: str) -> list: |
|
|
try: |
|
|
return loads(data) |
|
|
except JSONDecodeError: |
|
|
print("\n[Adv. Mapping] Pasting Old Infotext is not supported...\n") |
|
|
return DEFAULT_MAPPING |
|
|
|
|
|
|
|
|
def manual_entry(data: list, new: str, index: int) -> list: |
|
|
if index < 0: |
|
|
return data |
|
|
|
|
|
v = [round(float(val), 2) for val in new.split(",")] |
|
|
|
|
|
if v[1] < v[0]: |
|
|
v[0], v[1] = v[1], v[0] |
|
|
if v[3] < v[2]: |
|
|
v[2], v[3] = v[3], v[2] |
|
|
|
|
|
try: |
|
|
data[index][0] = f"{v[0]:.2f}:{v[1]:.2f}" |
|
|
data[index][1] = f"{v[2]:.2f}:{v[3]:.2f}" |
|
|
except IndexError: |
|
|
data.append([f"{v[0]:.2f}:{v[1]:.2f}", f"{v[2]:.2f}:{v[3]:.2f}", "1.0"]) |
|
|
|
|
|
return data |
|
|
|