-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathgenerate_icon.swift
More file actions
76 lines (65 loc) · 2.62 KB
/
Copy pathgenerate_icon.swift
File metadata and controls
76 lines (65 loc) · 2.62 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
import AppKit
// Generate an app icon from the eye.fill SF Symbol
let sizes: [(CGFloat, String)] = [
(16, "icon_16x16"),
(32, "icon_16x16@2x"),
(32, "icon_32x32"),
(64, "icon_32x32@2x"),
(128, "icon_128x128"),
(256, "icon_128x128@2x"),
(256, "icon_256x256"),
(512, "icon_256x256@2x"),
(512, "icon_512x512"),
(1024, "icon_512x512@2x"),
]
let iconsetPath = "AppIcon.iconset"
let fm = FileManager.default
try? fm.createDirectory(atPath: iconsetPath, withIntermediateDirectories: true)
for (size, name) in sizes {
let image = NSImage(size: NSSize(width: size, height: size))
image.lockFocus()
// Draw rounded rect background
let bgRect = NSRect(x: 0, y: 0, width: size, height: size)
let cornerRadius = size * 0.22
let bgPath = NSBezierPath(roundedRect: bgRect, xRadius: cornerRadius, yRadius: cornerRadius)
NSColor(calibratedRed: 0.15, green: 0.15, blue: 0.20, alpha: 1.0).setFill()
bgPath.fill()
// Draw the eye symbol in white
let symbolSize = size * 0.55
let config = NSImage.SymbolConfiguration(pointSize: symbolSize, weight: .medium)
if let symbol = NSImage(systemSymbolName: "eye.fill", accessibilityDescription: nil)?
.withSymbolConfiguration(config) {
// Create a white-tinted copy of the symbol
let tinted = NSImage(size: symbol.size)
tinted.lockFocus()
symbol.draw(in: NSRect(origin: .zero, size: symbol.size), from: .zero, operation: .sourceOver, fraction: 1.0)
NSColor.white.setFill()
NSRect(origin: .zero, size: symbol.size).fill(using: .sourceAtop)
tinted.unlockFocus()
let x = (size - tinted.size.width) / 2
let y = (size - tinted.size.height) / 2
tinted.draw(in: NSRect(x: x, y: y, width: tinted.size.width, height: tinted.size.height),
from: .zero, operation: .sourceOver, fraction: 1.0)
}
image.unlockFocus()
guard let tiff = image.tiffRepresentation,
let bitmap = NSBitmapImageRep(data: tiff),
let png = bitmap.representation(using: .png, properties: [:]) else {
print("Failed to render \(name)")
continue
}
try png.write(to: URL(fileURLWithPath: "\(iconsetPath)/\(name).png"))
}
// Convert iconset to icns
let proc = Process()
proc.executableURL = URL(fileURLWithPath: "/usr/bin/iconutil")
proc.arguments = ["-c", "icns", iconsetPath, "-o", "AppIcon.icns"]
try proc.run()
proc.waitUntilExit()
// Clean up iconset
try? fm.removeItem(atPath: iconsetPath)
if proc.terminationStatus == 0 {
print("Generated AppIcon.icns")
} else {
print("iconutil failed with status \(proc.terminationStatus)")
}