【问题标题】:Swift on MacOS - How to save NSImage to diskMacOS 上的 Swift - 如何将 NSImage 保存到磁盘
【发布时间】:2017-02-16 22:12:53
【问题描述】:

我有以下代码工作:

let myImage = NSImage(named: "my-image.png")

filter.setValue(myImage, forKey: kCIInputImageKey)
filter.setValue(0.5, forKey: kCIInputIntensityKey)

let resultImage = filter.outputImage

如何将过滤后的图像(以 PNG 格式)保存到磁盘?请注意,这是一个 UIImage 不可用的 MacOS 版本(Xcode 抛出:尝试导入时没有此类模块 'UIImage')

【问题讨论】:

    标签: swift macos macros nsimage


    【解决方案1】:

    您可以从您的 ciimage 过滤器结果创建一个核心图像上下文和 createCGImage。你可以这样做:

    import Cocoa
    
    class ViewController: NSViewController {
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            let context = CIContext()
            let desktopURL = FileManager.default.urls(for: .desktopDirectory, in: .userDomainMask).first!
            guard
                let filter = CIFilter(name: "CISepiaTone"),
                let imageURL = Bundle.main.url(forResource: "my-image", withExtension: "png"),
                let ciImage = CIImage(contentsOf: imageURL)
            else { return }
    
            filter.setValue(ciImage, forKey: kCIInputImageKey)
            filter.setValue(0.5, forKey: kCIInputIntensityKey)
    
            guard let result = filter.outputImage, let cgImage = context.createCGImage(result, from: result.extent)
            else { return }
    
            let destinationURL = desktopURL.appendingPathComponent("my-image.png")
            let nsImage = NSImage(cgImage: cgImage, size: ciImage.extent.size)
            if nsImage.pngWrite(to: destinationURL, options: .withoutOverwriting) {
                print("File saved")
            }
        }
    }
    

    您将需要这些扩展来获取 png 表示数据以将生成的图像写入磁盘:

    extension NSImage {
        var pngData: Data? {
            guard let tiffRepresentation = tiffRepresentation, let bitmapImage = NSBitmapImageRep(data: tiffRepresentation) else { return nil }
            return bitmapImage.representation(using: .png, properties: [:])
        }
        func pngWrite(to url: URL, options: Data.WritingOptions = .atomic) -> Bool {
            do {
                try pngData?.write(to: url, options: options)
                return true
            } catch {
                print(error)
                return false
            }
        }
    }
    

    【讨论】:

    • 工作就像一个魅力。谢谢!
    【解决方案2】:

    2021 |斯威夫特 5

    这个扩展:

    public extension NSImage {
        func save(to url: URL, format: NSBitmapImageRep.FileType, props: [NSBitmapImageRep.PropertyKey : Any] ) -> Result<URL, Error> {
            return self.representations.first
                .asNonOptional
                .map { $0 as? NSBitmapImageRep }
                .flatMap { data -> R<NSBitmapImageRep> in data.asNonOptional }
                .map { $0.representation(using: .jpeg, properties: props) }
                .flatMap{ $0.asNonOptional }
                .map { try? $0.write(to: url) }
                .map { $0.asNonOptional }
                .map { _ in url}
        }
    }
    
    public extension Optional {
        var asNonOptional : R<Wrapped> {
            if let val = self {
                return .success(val)
            } else {
                return .failure(CustomError("nil for optional value of type <\(Wrapped.self)>"))
            }
        }
    }
    
    public func CustomError(_ msg: String, code: Int = 0) -> Error {
        NSError(code: code, message: msg)
    }
    

    适用于最需要的文件格式并支持任何需要的属性。

    用法:

    _ = someImage.write(to: url, format: .png, props: [.compressionFactor : NSNumber(floatLiteral: 1.0)])
    
    _ = someImage.write(to: url, format: .jpeg, props: [.compressionFactor : NSNumber(floatLiteral: 1.0)])
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-02
      • 1970-01-01
      相关资源
      最近更新 更多