Skip to content

Instantly share code, notes, and snippets.

@ypujante
Created November 25, 2022 18:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ypujante/303f42d6e3259ecfaeb4c62de5fa850d to your computer and use it in GitHub Desktop.
Save ypujante/303f42d6e3259ecfaeb4c62de5fa850d to your computer and use it in GitHub Desktop.
Generate a macos iconset (.icns) from an svg file using Google Chrome
#!/usr/bin/env python3
import sys
import tempfile
from pathlib import Path
import subprocess
import os
import platform
scale = 1.0
# Account for scaling factor on macOS (requires PyObjC to work)
# Other solution: Set Google Chrome to run in "Low Resolution" mode
if platform.system() == 'Darwin':
try:
from AppKit import NSScreen
scale = NSScreen.mainScreen().backingScaleFactor()
except:
scale = 1.0
# input file should be svg
def renderIcon(tmpDir, size, iSvg, oPng):
size = int(size / scale)
html = f"""<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body style="margin:0;overflow:hidden">
<img style="padding; margin:0" src="{iSvg}" width="{size}" height="{size}"></img>
</body>
</html>
"""
htmlFile = tmpDir / "icon.html"
with htmlFile.open("w") as f:
f.write(html)
command = ["/Applications/Google Chrome.app/Contents/MacOS/Google Chrome",
"--headless",
f"--screenshot={oPng}",
f"--window-size={size},{size}",
"--default-background-color=0",
str(htmlFile)
]
subprocess.run(command)
if len(sys.argv) <= 1:
print("You must provide an svg file input")
sys.exit(1)
with tempfile.TemporaryDirectory() as tmpDir:
tmpDir = Path(tmpDir)
svgInput = Path(os.path.realpath(sys.argv[1]))
iconsDir = tmpDir / f"{svgInput.stem}.iconset"
os.mkdir(iconsDir)
for size in [512, 256, 128, 32, 16]:
renderIcon(tmpDir, size * 2, svgInput, iconsDir / f"icon_{size}x{size}@2x.png")
renderIcon(tmpDir, size, svgInput, iconsDir / f"icon_{size}x{size}.png")
output = svgInput.parent / f"{svgInput.stem}.icns" if len(sys.argv) <= 2 else Path(os.path.realpath(sys.argv[2]))
command = ["iconutil",
"-c", "icns",
"-o", output,
str(iconsDir) ]
subprocess.run(command)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment