Fix SIM2 PIN verification and replace Plymouth boot splash with rotating Bananarchy logo
This commit is contained in:
@@ -140,7 +140,101 @@ def main():
|
||||
splash.save(os.path.join(ARTWORK_DIR, "splash-240x320.png"), "PNG", optimize=True)
|
||||
splash.save(os.path.join(ARTWORK_DIR, "splash-240x320.ppm"), "PPM")
|
||||
|
||||
# 9. Project documentation banner (800x240)
|
||||
# 9. Plymouth rotating boot splash layers (stationary central A + rotating outer ring)
|
||||
import numpy as np
|
||||
from scipy import ndimage
|
||||
src_rgba = src.convert("RGBA")
|
||||
arr = np.array(src_rgba)
|
||||
rgb = arr[:, :, :3].astype(np.float32)
|
||||
r_ch, g_ch, b_ch = rgb[:, :, 0], rgb[:, :, 1], rgb[:, :, 2]
|
||||
lum = rgb.max(axis=2)
|
||||
|
||||
# Separate central A bananas from outer banana circle via distance transform
|
||||
is_yellow = (r_ch > 140) & (g_ch > 90) & (b_ch < 90)
|
||||
labeled, num = ndimage.label(is_yellow)
|
||||
center_yellow = np.zeros_like(is_yellow)
|
||||
outer_yellow = np.zeros_like(is_yellow)
|
||||
for i in range(1, num + 1):
|
||||
pts = np.argwhere(labeled == i)
|
||||
if len(pts) < 50:
|
||||
continue
|
||||
ymin, xmin = pts.min(axis=0)
|
||||
ymax, xmax = pts.max(axis=0)
|
||||
yc, xc = pts.mean(axis=0)
|
||||
rc = np.hypot(xc - 512.0, yc - 512.0)
|
||||
if (xmax - xmin) > 700 or rc > 280.0:
|
||||
outer_yellow |= (labeled == i)
|
||||
else:
|
||||
center_yellow |= (labeled == i)
|
||||
|
||||
dist_center = ndimage.distance_transform_edt(~center_yellow)
|
||||
dist_outer = ndimage.distance_transform_edt(~outer_yellow)
|
||||
y_grid, x_grid = np.ogrid[:1024, :1024]
|
||||
rad = np.hypot(x_grid - 512.0, y_grid - 512.0)
|
||||
fg_alpha = np.clip((lum - 10.0) / 28.0, 0.0, 1.0)
|
||||
|
||||
in_inner_core = np.clip((290.0 - rad) / 4.0, 0.0, 1.0) * np.clip((718.0 - y_grid) / 4.0, 0.0, 1.0)
|
||||
near_center_tip = (
|
||||
np.clip((dist_outer - dist_center + 4.0) / 4.0, 0.0, 1.0)
|
||||
* np.clip((27.0 - dist_center) / 3.0, 0.0, 1.0)
|
||||
* np.clip((y_grid - 91.0) / 2.5, 0.0, 1.0)
|
||||
* np.clip((722.0 - y_grid) / 3.0, 0.0, 1.0)
|
||||
)
|
||||
center_weight = np.maximum(in_inner_core, near_center_tip)
|
||||
ring_weight = 1.0 - center_weight
|
||||
|
||||
center_rgba = arr.copy()
|
||||
center_rgba[:, :, 3] = (fg_alpha * center_weight * 255.0).astype(np.uint8)
|
||||
ring_rgba = arr.copy()
|
||||
ring_rgba[:, :, 3] = (fg_alpha * ring_weight * 255.0).astype(np.uint8)
|
||||
|
||||
err_rgba = arr.copy()
|
||||
err_rgba[:, :, 0] = np.clip(rgb[:, :, 0] * 1.1, 0, 255).astype(np.uint8)
|
||||
err_rgba[:, :, 1] = (rgb[:, :, 1] * 0.22).astype(np.uint8)
|
||||
err_rgba[:, :, 2] = (rgb[:, :, 2] * 0.18).astype(np.uint8)
|
||||
err_rgba[:, :, 3] = (fg_alpha * 255.0).astype(np.uint8)
|
||||
|
||||
ply_size = 168
|
||||
ply_center_img = Image.fromarray(center_rgba).resize((ply_size, ply_size), Image.Resampling.LANCZOS)
|
||||
ply_ring_img = Image.fromarray(ring_rgba).resize((ply_size, ply_size), Image.Resampling.LANCZOS)
|
||||
ply_error_img = Image.fromarray(err_rgba).resize((ply_size, ply_size), Image.Resampling.LANCZOS)
|
||||
|
||||
# Title image for Plymouth splash ("BANANARCHY")
|
||||
ply_title_img = Image.new("RGBA", (180, 28), (0, 0, 0, 0))
|
||||
ptdraw = ImageDraw.Draw(ply_title_img)
|
||||
ptb = ptdraw.textbbox((0, 0), title_text, font=font_title)
|
||||
ptw = ptb[2] - ptb[0]
|
||||
ptdraw.text(((180 - ptw) // 2, 2), title_text, fill=(255, 214, 10, 255), font=font_title)
|
||||
|
||||
ply_center_img.save(os.path.join(ARTWORK_DIR, "plymouth-center.png"), "PNG", optimize=True)
|
||||
ply_ring_img.save(os.path.join(ARTWORK_DIR, "plymouth-ring.png"), "PNG", optimize=True)
|
||||
ply_error_img.save(os.path.join(ARTWORK_DIR, "plymouth-error.png"), "PNG", optimize=True)
|
||||
ply_title_img.save(os.path.join(ARTWORK_DIR, "plymouth-title.png"), "PNG", optimize=True)
|
||||
|
||||
for root_base in (
|
||||
os.path.join(BASE_DIR, "overlay", "rootfs"),
|
||||
os.path.join(BASE_DIR, "rootfs"),
|
||||
):
|
||||
if not os.path.isdir(root_base):
|
||||
continue
|
||||
ply_dir = os.path.join(root_base, "usr", "share", "plymouth")
|
||||
theme_dir = os.path.join(ply_dir, "themes", "pmos-spin")
|
||||
os.makedirs(theme_dir, exist_ok=True)
|
||||
ply_center_img.save(os.path.join(theme_dir, "center.png"), "PNG", optimize=True)
|
||||
ply_ring_img.save(os.path.join(theme_dir, "ring.png"), "PNG", optimize=True)
|
||||
ply_error_img.save(os.path.join(theme_dir, "error.png"), "PNG", optimize=True)
|
||||
ply_title_img.save(os.path.join(theme_dir, "title.png"), "PNG", optimize=True)
|
||||
for stale in ("right.png", "top.png", "left.png"):
|
||||
stale_path = os.path.join(theme_dir, stale)
|
||||
if os.path.exists(stale_path):
|
||||
os.remove(stale_path)
|
||||
icon_rgba = Image.fromarray(arr.copy())
|
||||
icon_rgba.putalpha(Image.fromarray((fg_alpha * 255.0).astype(np.uint8)))
|
||||
icon_rgba.resize((128, 128), Image.Resampling.LANCZOS).save(
|
||||
os.path.join(ply_dir, "bizcom.png"), "PNG", optimize=True
|
||||
)
|
||||
|
||||
# 10. Project documentation banner (800x240)
|
||||
banner = make_canvas(800, 240, (1, 1, 1))
|
||||
paste_centered(banner, src, 204, 118, 120)
|
||||
bdraw = ImageDraw.Draw(banner)
|
||||
|
||||
Reference in New Issue
Block a user