swift - 在本地以不同格式保存 NSI​​mage

标签 swift macos

我需要允许用户将 NSImage 保存到本地文件。

所以我正在使用来自这个 SO answer 的那些扩展可以将图片保存为PNG格式

extension NSBitmapImageRep {
    var png: Data? {
        return representation(using: .png, properties: [:])
    }
}
extension Data {
    var bitmap: NSBitmapImageRep? {
        return NSBitmapImageRep(data: self)
    }
}
extension NSImage {
    var png: Data? {
        return tiffRepresentation?.bitmap?.png

    }
    func savePNG(to url: URL) -> Bool {
        do {
            try png?.write(to: url)
            return true
        } catch {
            print(error)
            return false
        }

    }
}

有没有更简单的方法将 NSImage 保存为不同的格式,如 JPEG、TIFF、BMP 等

最佳答案

您可以创建一个自定义方法来允许您指定任何图像类型以及您希望保存 NSI​​mage 的目录。您还可以将目标目录的默认值设置为当前目录,因此如果您不传递目录 url,它将保存到当前目录:

extension NSImage {
    func save(as fileName: String, fileType: NSBitmapImageRep.FileType = .jpeg, at directory: URL = URL(fileURLWithPath: FileManager.default.currentDirectoryPath)) -> Bool {
        guard let tiffRepresentation = tiffRepresentation, directory.isDirectory, !fileName.isEmpty else { return false }
        do {
            try NSBitmapImageRep(data: tiffRepresentation)?
                .representation(using: fileType, properties: [:])?
                .write(to: directory.appendingPathComponent(fileName).appendingPathExtension(fileType.pathExtension))
            return true
        } catch {
            print(error)
            return false
        }
    }
}

您还需要确保传递给您的方法的 url 是一个目录 url。您可以使用 URL resourceValues 方法获取 url isDirectoryKey 值并检查它是否为真:

extension URL {
    var isDirectory: Bool {
       return (try? resourceValues(forKeys: [.isDirectoryKey]))?.isDirectory == true
    }
}

您还可以扩展 NSBitmapImageRep.FileType 以提供关联的文件路径扩展名:

extension NSBitmapImageRep.FileType {
    var pathExtension: String {
        switch self {
        case .bmp:
            return "bmp"
        case .gif:
            return "gif"
        case .jpeg:
            return "jpg"
        case .jpeg2000:
            return "jp2"
        case .png:
            return "png"
        case .tiff:
            return "tif"
        }
    }
}

Playground 测试:

let desktopDirectory = FileManager.default.urls(for: .desktopDirectory, in: .userDomainMask).first!
// lets change the current directory to the desktop directory
FileManager.default.changeCurrentDirectoryPath(desktopDirectory.path)

// get your nsimage
let picture  = NSImage(contentsOf: URL(string: "/image/Xs4RX.jpg")!)!

// this will save to the current directory
if picture.save(as: "profile") {
    print("file saved as profile.jpg which is the default type")
}
if picture.save(as: "profile", fileType: .png) {
    print("file saved as profile.png")
}
if picture.save(as: "profile", fileType: .tiff) {
    print("file saved as profile.tif")
}
if picture.save(as: "profile", fileType: .gif) {
    print("file saved as profile.gif")
}
if picture.save(as: "profile", fileType: .jpeg2000) {
    print("file saved as profile.jp2")
}

// you can also chose a choose another directory without the need to change the current directory
let url = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
if picture.save(as: "profile", at: url) {
    print("file saved as profile.jpg at documentDirectory")
}

关于swift - 在本地以不同格式保存 NSI​​mage,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46432709/

相关文章:

php - is_dir 在 apache 中的符号链接(symbolic link)上返回 false

macos - 如何从 bash 脚本中识别当前的终端仿真器?

swift - 来自多个变量的字符串插值导致表达式太复杂而无法解决

swift - 境界 0.99 Swift 让境界 = 试试! Realm ()

Swift:具有通用函数和约束的 inout

ios - 意外删除 Main.Storyboard

macos - 在非事件 NSWindow 中刷新 NSTableView

ios - Swift CollectionView 设置滚动位置

swift - MacOS 模态对话框,如 NSAlert

macos - 在 OS X 中通过 perl 控制鼠标