Podlite 1.9: radio icon

New launcher icon (the Podcasts Radio pack, master in art/icon-master.png). The status-bar icon
was cut out of the old headphones artwork; make_icons.py now draws a white radio silhouette.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
XoséandClaude Opus 5.5 committed 2026-10-19 18:57:02 +02:00
1 parent 042364b45c
commit c673a0ba5d
14 files changed
+26 -24

No files matched your search

+21 -19
View File
@@ -1,9 +1,9 @@
"""Draws Podlite's PNG icons for ldpi (Galaxy Mini), mdpi and hdpi.
The launcher icon (res/drawable-*/ic_launcher.png) comes from the supplied
Audiobookshelf icon pack and is not generated here. The notification icon is
cut out of that same artwork (art/icon_master_512.png): the white headphones
and equalizer become a white silhouette, as Android 2.3's status bar expects.
"Podcasts Radio" icon pack (master in art/icon-master.png) and is not generated
here. The notification icon is a white silhouette of that radio, as Android
2.3's status bar expects.
Android 2.x has no vector drawables, so the player icons are rendered at 4x and
downsampled for smooth edges.
@@ -33,22 +33,24 @@ def save(img, px, folder, name):
def status_silhouette():
"""White mask of the icon's light parts (headphones, bars, waves) on transparency."""
src = Image.open(os.path.join(ROOT, "art", "icon_master_512.png")).convert("RGBA")
out = Image.new("RGBA", src.size, (0, 0, 0, 0))
sp, op = src.load(), out.load()
for y in range(src.size[1]):
for x in range(src.size[0]):
r, g, b, a = sp[x, y]
# the purple background has a low green channel; the white/lilac artwork a high one
level = min(255, max(0, (g - 80) * 255 // 50))
op[x, y] = (255, 255, 255, level * a // 255)
box = out.getbbox()
out = out.crop(box)
side = max(out.size)
sq = Image.new("RGBA", (side, side), (0, 0, 0, 0))
sq.paste(out, ((side - out.size[0]) // 2, (side - out.size[1]) // 2))
return sq
"""White silhouette of the launcher icon's old radio (handle, grille, two knobs) on transparency:
Android 2.3's status bar expects a light glyph, not the colour artwork."""
S = 24 * 32 # drawn on a 24-unit grid, supersampled
u = lambda v: int(round(v * 32))
m = Image.new("L", (S, S), 0)
d = ImageDraw.Draw(m)
d.arc((u(6), u(1.2), u(18), u(11)), 200, 340, fill=255, width=u(1.8)) # carrying handle
d.rounded_rectangle((u(1.5), u(6.5), u(22.5), u(21.5)), radius=u(3.5), fill=255)
d.rounded_rectangle((u(4), u(9), u(14), u(19)), radius=u(1.2), fill=0) # grille window
for i in range(3): # grille bars
y = 10.6 + i * 2.9
d.rounded_rectangle((u(5.2), u(y), u(12.8), u(y + 1.5)), radius=u(0.7), fill=255)
for cy, r in ((11.6, 2.4), (17.0, 2.0)): # knobs as rings
d.ellipse((u(18 - r), u(cy - r), u(18 + r), u(cy + r)), fill=0)
d.ellipse((u(18 - r + 1.1), u(cy - r + 1.1), u(18 + r - 1.1), u(cy + r - 1.1)), fill=255)
out = Image.new("RGBA", (S, S), (255, 255, 255, 0))
out.putalpha(m)
return out
def status(sil, px, folder):