Skip to content

Instantly share code, notes, and snippets.

@cumulus13
Created December 22, 2025 10:33
Show Gist options
  • Select an option

  • Save cumulus13/3ad1d935a5fd28f91e1c1508beb4d41f to your computer and use it in GitHub Desktop.

Select an option

Save cumulus13/3ad1d935a5fd28f91e1c1508beb4d41f to your computer and use it in GitHub Desktop.
Convert png to ico image with multiple sizes.
#!/usr/bin/env python3
# File: png2ico.py
# Author: Hadi Cahyadi <cumulus13@gmail.com>
# Date: 2025-12-22
# Description: Convert png to ico image with multiple sizes.
# License: MIT
from pathlib import Path
from PIL import Image
import sys
# All common icon sizes
ALL_SIZES = [16, 20, 24, 32, 40, 48, 64, 72, 96, 128, 256, 512]
def make_square(img: Image.Image, size: int):
"""Resize and pad to a transparent square"""
img = img.convert("RGBA")
w, h = img.size
scale = min(size / w, size / h)
new_w, new_h = int(w * scale), int(h * scale)
resized = img.resize((new_w, new_h), Image.LANCZOS)
canvas = Image.new("RGBA", (size, size), (0, 0, 0, 0))
canvas.paste(resized, ((size - new_w)//2, (size - new_h)//2), resized)
return canvas
def png_to_icos(png_path: Path):
with Image.open(png_path) as img:
img = img.convert("RGBA")
base = png_path.stem
out_dir = png_path.parent
print(f"[INFO] Processing {png_path.name}...")
# Save each measure as a separate file
for s in ALL_SIZES:
square = make_square(img, s)
out_path = out_dir / f"{base}_{s}.ico"
square.save(out_path, format="ICO", sizes=[(s, s)])
print(f" - {out_path.name}")
# Save one multi-size file
multi_path = out_dir / f"{base}.ico"
img.save(multi_path, format="ICO", sizes=[(s, s) for s in ALL_SIZES])
print(f" - {multi_path.name} (multi-size)")
print("[DONE]\n")
def main():
if len(sys.argv) < 2:
print("Usage: python png2ico.py <file.png>")
return
png_path = Path(sys.argv[1])
if not png_path.exists():
print(f"[ERR] File {png_path} not found.")
return
if png_path.suffix.lower() != ".png":
print("[ERR] Only PNG files are supported.")
return
png_to_icos(png_path)
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment