Remove accidental binary additions
|
Before Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 22 KiB |
|
Before Width: | Height: | Size: 27 KiB |
|
Before Width: | Height: | Size: 31 KiB |
|
Before Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 23 KiB |
|
Before Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 28 KiB |
|
Before Width: | Height: | Size: 23 KiB |
BIN
romancolumn.webp
|
Before Width: | Height: | Size: 43 KiB |
130
shift_paths.py
@ -1,130 +0,0 @@
|
|||||||
import os
|
|
||||||
import re
|
|
||||||
import xml.etree.ElementTree as ET
|
|
||||||
import json
|
|
||||||
|
|
||||||
def parse_viewbox(root):
|
|
||||||
vb = root.get('viewBox')
|
|
||||||
if vb:
|
|
||||||
parts = [float(x) for x in vb.split()]
|
|
||||||
if len(parts) == 4:
|
|
||||||
return parts[2], parts[3] # Width, Height
|
|
||||||
width = root.get('width')
|
|
||||||
height = root.get('height')
|
|
||||||
if width and height:
|
|
||||||
return float(width.replace('in','').replace('px','')) * 96, float(height.replace('in','').replace('px','')) * 96 # rough approx if units
|
|
||||||
return 30.0, 40.0 # Fallback
|
|
||||||
|
|
||||||
def tokenize_path(d):
|
|
||||||
# Split by commands and numbers.
|
|
||||||
# Commands: M, m, L, l, V, v, H, h, C, c, S, s, Q, q, T, t, A, a, Z, z
|
|
||||||
# Numbers: float regex
|
|
||||||
tokens = re.findall(r'[a-zA-Z]|[-+]?(?:\d*\.\d+|\d+)(?:[eE][-+]?\d+)?', d)
|
|
||||||
return tokens
|
|
||||||
|
|
||||||
def is_num(t):
|
|
||||||
try:
|
|
||||||
float(t)
|
|
||||||
return True
|
|
||||||
except:
|
|
||||||
return False
|
|
||||||
|
|
||||||
def shift_d(d, dx, dy):
|
|
||||||
tokens = tokenize_path(d)
|
|
||||||
new_tokens = []
|
|
||||||
|
|
||||||
current_cmd = ''
|
|
||||||
i = 0
|
|
||||||
|
|
||||||
# SVG 1.1: first command must be M or m. m treated as absolute M.
|
|
||||||
|
|
||||||
while i < len(tokens):
|
|
||||||
t = tokens[i]
|
|
||||||
if not is_num(t):
|
|
||||||
current_cmd = t
|
|
||||||
new_tokens.append(t)
|
|
||||||
i += 1
|
|
||||||
|
|
||||||
# Special case for 'm' at start: first pair absolute, rest relative
|
|
||||||
if current_cmd == 'm' and len(new_tokens) == 1:
|
|
||||||
# First pair
|
|
||||||
if i+1 < len(tokens):
|
|
||||||
x = float(tokens[i]) + dx
|
|
||||||
y = float(tokens[i+1]) + dy
|
|
||||||
new_tokens.extend([f"{x:.4f}", f"{y:.4f}"])
|
|
||||||
i += 2
|
|
||||||
# Subsequent pairs are relative line-tos, do NOT shift
|
|
||||||
|
|
||||||
continue
|
|
||||||
|
|
||||||
# It's a number, implies continuation of previous command or implicit line-to
|
|
||||||
# If we are here, we are processing parameters for current_cmd
|
|
||||||
|
|
||||||
# Determine if absolute coordinate
|
|
||||||
if current_cmd in ['M', 'L', 'C', 'S', 'Q', 'T']:
|
|
||||||
# Pairs of X, Y
|
|
||||||
x = float(tokens[i]) + dx
|
|
||||||
y = float(tokens[i+1]) + dy
|
|
||||||
new_tokens.extend([f"{x:.4f}", f"{y:.4f}"])
|
|
||||||
i += 2
|
|
||||||
elif current_cmd == 'V':
|
|
||||||
y = float(tokens[i]) + dy
|
|
||||||
new_tokens.append(f"{y:.4f}")
|
|
||||||
i += 1
|
|
||||||
elif current_cmd == 'H':
|
|
||||||
x = float(tokens[i]) + dx
|
|
||||||
new_tokens.append(f"{x:.4f}")
|
|
||||||
i += 1
|
|
||||||
elif current_cmd == 'A':
|
|
||||||
# rx ry rot large sweep x y
|
|
||||||
# skip 5
|
|
||||||
new_tokens.extend(tokens[i:i+5])
|
|
||||||
i += 5
|
|
||||||
x = float(tokens[i]) + dx
|
|
||||||
y = float(tokens[i+1]) + dy
|
|
||||||
new_tokens.extend([f"{x:.4f}", f"{y:.4f}"])
|
|
||||||
i += 2
|
|
||||||
else:
|
|
||||||
# Relative commands (m, l, c, s, q, t, v, h, a) - do NOT shift
|
|
||||||
# Just copy tokens until next command
|
|
||||||
# But we need to know how many args to consume?
|
|
||||||
# Easier: just iterate until next alpha token
|
|
||||||
new_tokens.append(t)
|
|
||||||
i += 1
|
|
||||||
|
|
||||||
return ' '.join(new_tokens)
|
|
||||||
|
|
||||||
base_dir = 'output_webp'
|
|
||||||
final_paths = {}
|
|
||||||
|
|
||||||
for num in range(10):
|
|
||||||
filename = os.path.join(base_dir, f'{num}.svg')
|
|
||||||
if os.path.exists(filename):
|
|
||||||
try:
|
|
||||||
tree = ET.parse(filename)
|
|
||||||
root = tree.getroot()
|
|
||||||
|
|
||||||
w, h = parse_viewbox(root)
|
|
||||||
cx, cy = w/2, h/2
|
|
||||||
|
|
||||||
# Find path
|
|
||||||
ns = {'svg': 'http://www.w3.org/2000/svg'}
|
|
||||||
path = root.find('.//svg:path', ns)
|
|
||||||
if not path:
|
|
||||||
path = root.find('.//{http://www.w3.org/2000/svg}path')
|
|
||||||
if not path:
|
|
||||||
for elem in root.iter():
|
|
||||||
if elem.tag.endswith('path'):
|
|
||||||
path = elem
|
|
||||||
break
|
|
||||||
|
|
||||||
if path is not None:
|
|
||||||
d = path.get('d')
|
|
||||||
if d:
|
|
||||||
# Shift so center is 0,0
|
|
||||||
shifted = shift_d(d, -cx, -cy)
|
|
||||||
final_paths[str(num)] = shifted
|
|
||||||
except Exception as e:
|
|
||||||
print(f"Error {num}: {e}")
|
|
||||||
|
|
||||||
print(json.dumps(final_paths))
|
|
||||||