import AppKit let arguments = CommandLine.arguments guard arguments.count > 3 else { print("Usage: swift process_icon.swift ") exit(1) } let inputPath = arguments[1] let outputPath = arguments[2] let hexColor = arguments[3].replacingOccurrences(of: "#", with: "") let scaleFactor = arguments.count > 4 ? Double(arguments[4]) ?? 0.8 : 0.8 func colorFromHex(_ hex: String) -> NSColor { var rgbValue: UInt64 = 0 Scanner(string: hex).scanHexInt64(&rgbValue) let r = CGFloat((rgbValue & 0xFF0000) >> 16) / 255.0 let g = CGFloat((rgbValue & 0x00FF00) >> 8) / 255.0 let b = CGFloat(rgbValue & 0x0000FF) / 255.0 return NSColor(red: r, green: g, blue: b, alpha: 1.0) } guard let inputImage = NSImage(contentsOfFile: inputPath) else { print("Error: Could not load input image") exit(1) } // Fixed size for launcher icon (e.g. 1024x1024) let size = NSSize(width: 1024, height: 1024) let outputImage = NSImage(size: size) outputImage.lockFocus() // Fill background let backgroundColor = colorFromHex(hexColor) backgroundColor.set() NSBezierPath(rect: NSRect(origin: .zero, size: size)).fill() // Draw input image centered let inputSize = inputImage.size let ratio = min(size.width / inputSize.width, size.height / inputSize.height) * CGFloat(scaleFactor) let targetSize = NSSize(width: inputSize.width * ratio, height: inputSize.height * ratio) let origin = NSPoint(x: (size.width - targetSize.width) / 2, y: (size.height - targetSize.height) / 2) inputImage.draw(in: NSRect(origin: origin, size: targetSize), from: .zero, operation: .sourceOver, fraction: 1.0) outputImage.unlockFocus() guard let tiffData = outputImage.tiffRepresentation, let bitmapImage = NSBitmapImageRep(data: tiffData), let pngData = bitmapImage.representation(using: .png, properties: [:]) else { print("Error: Could not convert to PNG") exit(1) } do { try pngData.write(to: URL(fileURLWithPath: outputPath)) print("Success: \(outputPath) created") } catch { print("Error: Could not write file: \(error)") exit(1) }