d2
BIN
public/apple-touch-icon.png
Normal file
|
After Width: | Height: | Size: 9.9 KiB |
2909
public/d2.html
BIN
public/favicon-16x16.png
Normal file
|
After Width: | Height: | Size: 655 B |
BIN
public/favicon-256.png
Normal file
|
After Width: | Height: | Size: 8.0 KiB |
BIN
public/favicon-32x32.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
public/favicon.ico
Normal file
|
After Width: | Height: | Size: 7.6 KiB |
BIN
public/favicon.png
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
20
public/favicon.svg
Normal file
@@ -0,0 +1,20 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="64" height="64" viewBox="0 0 64 64" role="img" aria-label="App.model">
|
||||
<defs>
|
||||
<linearGradient id="g" x1="0" x2="1" y1="0" y2="1">
|
||||
<stop offset="0" stop-color="#60a5fa"/>
|
||||
<stop offset="1" stop-color="#818cf8"/>
|
||||
</linearGradient>
|
||||
<filter id="s" x="-20%" y="-20%" width="140%" height="140%">
|
||||
<feDropShadow dx="0" dy="2" stdDeviation="4" flood-color="#0f172a" flood-opacity="0.6"/>
|
||||
</filter>
|
||||
</defs>
|
||||
|
||||
<rect x="2" y="2" width="60" height="60" rx="12" ry="12" fill="url(#g)" filter="url(#s)"/>
|
||||
|
||||
<g transform="translate(32,34) scale(0.9)">
|
||||
<path d="M-12,-8 L0,-22 L12,-8 Z" fill="#0f172a" opacity="0.95"/>
|
||||
<rect x="-10" y="-8" width="20" height="16" rx="3" ry="3" fill="#0f172a" opacity="0.95"/>
|
||||
<rect x="-3" y="0" width="6" height="8" rx="1" ry="1" fill="#60a5fa"/>
|
||||
<circle cx="10" cy="-4" r="3" fill="#fbbf24" stroke="#fff5" stroke-width="0.6"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 960 B |
69
src/ico.py
@@ -1,14 +1,65 @@
|
||||
from PIL import Image
|
||||
# python
|
||||
from pathlib import Path
|
||||
import cairosvg
|
||||
from PIL import Image
|
||||
|
||||
# Convert SVG to PNG first
|
||||
png_path = "./public/img/favicon.png"
|
||||
ico_path = "./public/img/favicon.ico"
|
||||
PUBLIC = Path("./public")
|
||||
PUBLIC.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
cairosvg.svg2png(url="./public/img/favicon.svg", write_to=png_path)
|
||||
# SVG content for `public/favicon.svg`
|
||||
SVG = """<svg xmlns="http://www.w3.org/2000/svg" width="64" height="64" viewBox="0 0 64 64" role="img" aria-label="App.model">
|
||||
<defs>
|
||||
<linearGradient id="g" x1="0" x2="1" y1="0" y2="1">
|
||||
<stop offset="0" stop-color="#60a5fa"/>
|
||||
<stop offset="1" stop-color="#818cf8"/>
|
||||
</linearGradient>
|
||||
<filter id="s" x="-20%" y="-20%" width="140%" height="140%">
|
||||
<feDropShadow dx="0" dy="2" stdDeviation="4" flood-color="#0f172a" flood-opacity="0.6"/>
|
||||
</filter>
|
||||
</defs>
|
||||
|
||||
# Convert PNG → ICO
|
||||
img = Image.open(png_path)
|
||||
img.save(ico_path, format='ICO', sizes=[(32,32),(16,16), (48,48), (64,64)])
|
||||
<rect x="2" y="2" width="60" height="60" rx="12" ry="12" fill="url(#g)" filter="url(#s)"/>
|
||||
|
||||
ico_path
|
||||
<g transform="translate(32,34) scale(0.9)">
|
||||
<path d="M-12,-8 L0,-22 L12,-8 Z" fill="#0f172a" opacity="0.95"/>
|
||||
<rect x="-10" y="-8" width="20" height="16" rx="3" ry="3" fill="#0f172a" opacity="0.95"/>
|
||||
<rect x="-3" y="0" width="6" height="8" rx="1" ry="1" fill="#60a5fa"/>
|
||||
<circle cx="10" cy="-4" r="3" fill="#fbbf24" stroke="#fff5" stroke-width="0.6"/>
|
||||
</g>
|
||||
</svg>
|
||||
"""
|
||||
|
||||
svg_path = PUBLIC / "favicon.svg"
|
||||
svg_path.write_text(SVG, encoding="utf-8")
|
||||
|
||||
# Render a high-resolution source PNG (256x256) from the SVG
|
||||
base_png = PUBLIC / "favicon-256.png"
|
||||
cairosvg.svg2png(url=str(svg_path), write_to=str(base_png), output_width=256, output_height=256)
|
||||
|
||||
# Produce PNG icons at required sizes
|
||||
sizes_and_names = [
|
||||
(32, PUBLIC / "favicon-32x32.png"),
|
||||
(16, PUBLIC / "favicon-16x16.png"),
|
||||
(180, PUBLIC / "apple-touch-icon.png"),
|
||||
]
|
||||
|
||||
with Image.open(base_png) as im:
|
||||
im = im.convert("RGBA")
|
||||
for size, out_path in sizes_and_names:
|
||||
icon = im.resize((size, size), resample=Image.LANCZOS)
|
||||
icon.save(out_path, format="PNG")
|
||||
|
||||
# Save multi-size ICO (source should be sufficiently large for quality)
|
||||
ico_path = PUBLIC / "favicon.ico"
|
||||
im.save(ico_path, format="ICO", sizes=[(16,16), (32,32), (48,48), (64,64)])
|
||||
|
||||
# Optionally remove the intermediate 256 PNG
|
||||
# base_png.unlink()
|
||||
|
||||
print("Created:", *[str(p) for p in [
|
||||
svg_path,
|
||||
PUBLIC / "favicon-32x32.png",
|
||||
PUBLIC / "favicon-16x16.png",
|
||||
PUBLIC / "apple-touch-icon.png",
|
||||
PUBLIC / "favicon.ico"
|
||||
]])
|
||||