File size: 4,253 Bytes
7bed60d |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 |
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)
# print("\nAdv. Preview:")
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])
# weight = W
# print(f" [{y_from:4d}:{y_to:4d}, {x_from:4d}:{x_to:4d}] = {weight:.2f}")
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
|