Polish dashboard UI to match Mento mockup with IRANSans and brand assets.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,81 @@
|
||||
"""Cut black background only via edge flood-fill — keep black face screen."""
|
||||
from collections import deque
|
||||
from pathlib import Path
|
||||
|
||||
from PIL import Image
|
||||
|
||||
src = Path(r"e:\projeha\crm\apps\web\public\brand\Mento-ai.png")
|
||||
dst = Path(r"e:\projeha\crm\apps\web\public\brand\mento-ai-avatar.png")
|
||||
|
||||
img = Image.open(src).convert("RGBA")
|
||||
w, h = img.size
|
||||
px = img.load()
|
||||
|
||||
def is_bg(r, g, b, a):
|
||||
# near-black background plate (not cyan glow)
|
||||
if a < 10:
|
||||
return True
|
||||
if r < 40 and g < 40 and b < 45:
|
||||
return True
|
||||
if r < 55 and g < 55 and b < 60 and (r + g + b) < 150:
|
||||
# still bg if not cyan-tinted
|
||||
if b < g + 15 and g < r + 15:
|
||||
return True
|
||||
return False
|
||||
|
||||
visited = [[False] * w for _ in range(h)]
|
||||
q = deque()
|
||||
|
||||
# seed from all edge pixels that look like background
|
||||
for x in range(w):
|
||||
for y in (0, h - 1):
|
||||
r, g, b, a = px[x, y]
|
||||
if is_bg(r, g, b, a):
|
||||
q.append((x, y))
|
||||
visited[y][x] = True
|
||||
for y in range(h):
|
||||
for x in (0, w - 1):
|
||||
if not visited[y][x]:
|
||||
r, g, b, a = px[x, y]
|
||||
if is_bg(r, g, b, a):
|
||||
q.append((x, y))
|
||||
visited[y][x] = True
|
||||
|
||||
while q:
|
||||
x, y = q.popleft()
|
||||
px[x, y] = (0, 0, 0, 0)
|
||||
for nx, ny in ((x - 1, y), (x + 1, y), (x, y - 1), (x, y + 1)):
|
||||
if 0 <= nx < w and 0 <= ny < h and not visited[ny][nx]:
|
||||
r, g, b, a = px[nx, ny]
|
||||
if is_bg(r, g, b, a):
|
||||
visited[ny][nx] = True
|
||||
q.append((nx, ny))
|
||||
|
||||
bbox = img.getbbox()
|
||||
if bbox:
|
||||
pad = 20
|
||||
l, t, r, btm = bbox
|
||||
img = img.crop(
|
||||
(max(0, l - pad), max(0, t - pad), min(w, r + pad), min(h, btm + pad))
|
||||
)
|
||||
|
||||
# fit into square canvas keeping aspect
|
||||
ow, oh = img.size
|
||||
side = max(ow, oh)
|
||||
canvas = Image.new("RGBA", (side, side), (0, 0, 0, 0))
|
||||
canvas.paste(img, ((side - ow) // 2, (side - oh) // 2))
|
||||
canvas = canvas.resize((512, 512), Image.Resampling.LANCZOS)
|
||||
canvas.save(dst, "PNG", optimize=True)
|
||||
|
||||
# stats
|
||||
a = [p[3] for p in canvas.getdata()]
|
||||
print(
|
||||
"saved",
|
||||
dst,
|
||||
"zero_a",
|
||||
sum(1 for x in a if x == 0),
|
||||
"corner",
|
||||
canvas.getpixel((0, 0)),
|
||||
"center",
|
||||
canvas.getpixel((256, 256)),
|
||||
)
|
||||
Reference in New Issue
Block a user