首页 > 解决方案 > 如何在 macOS 上为文档获取图标?

问题描述

我正在寻找 macOS 上的命令行工具,它可以将指定文档或文件的图标文件写入磁盘。qlmanage可以创建缩略图或预览,但就我而言,我想获取图标文件。

手册页提到了图标模式,但我找不到任何组合来使它工作。有谁知道这是如何工作的或有替代方案?

% qlmanage -h
Usage: qlmanage [OPTIONS] path...
    [...]
    -i      Compute thumbnail in icon mode

谢谢!

标签: macosfinderquicklook

解决方案


我不知道有任何实用程序可以执行此操作,但您可以在https://github.com/apple/swift-argument-parser包的帮助下轻松编写自己的程序,并且NSWorkspace

以下示例代码使用第一种方法。

示例项目

  • Xcode - 新项目
  • 选择 macOS 和命令行实用程序
  • 添加https://github.com/apple/swift-argument-parserSwift 包
  • 复制并粘贴下面的代码
import AppKit
import ArgumentParser

final class StderrOutputStream: TextOutputStream {
    func write(_ string: String) {
        FileHandle.standardError.write(Data(string.utf8))
    }
}

struct Icon: ParsableCommand {
    static var configuration = CommandConfiguration(
        commandName: "icon",
        abstract: "Get the workspace icon and save it as a PNG image.",
        version: "0.0.1"
    )
    
    @Argument(help: "Path to a file.")
    var input: String
    
    @Argument(help: "Output file.")
    var output: String
    
    @Option(name: .shortAndLong, help: "Icon size.")
    var size: Int = 512
    
    mutating func run() throws {
        if !FileManager.default.fileExists(atPath: input) {
            var stderr = StderrOutputStream()
            print("File not found: \(input)", to: &stderr)
            throw ExitCode(-1)
        }
        
        // Get NSImage with multiple representations (sizes)
        let icon = NSWorkspace.shared.icon(forFile: input)
        
        // Propose some size to get as accurate as possible representation size
        var proposedRect = NSRect(x: 0, y: 0, width: size, height: size)
        
        guard let cgRef = icon.cgImage(forProposedRect: &proposedRect, context: nil, hints: nil) else {
            var stderr = StderrOutputStream()
            print("Internal error: unable to get CGImage from NSImage", to: &stderr)
            throw ExitCode(-2)
        }
        
        do {
            // Get PNG representation
            let data = NSBitmapImageRep(cgImage: cgRef).representation(using: .png, properties: [:])
            // Save it to a file
            try data?.write(to: URL(fileURLWithPath: output), options: .atomic)
        }
        catch {
            var stderr = StderrOutputStream()
            print("Failed to save icon: \(error)", to: &stderr)
            throw ExitCode(-3)
        }
        
        print("Icon (\(size)x\(size)) saved to: \(output)")
    }
}

Icon.main()

推荐阅读