Save NSImageView to disk as png/jpg

574 Views Asked by At

I'm trying to create an image from the contents of (all subviews) an NSImageView and save it to disk on a Mac. Right now the step of writing it to disk is failing. As I step through the code in the debugger, I notice that imageData doesn't appear to be created properly. The Variables View shows imageData's value as some and when I look deeper the field backing.bytes is nil.

enter image description here

My guess is this line:

let imageData: Data! = rep!.representation(using: NSBitmapImageRep.FileType.png, properties: [:])

is failing. Here is the full code I am using:

class ExportableImageView: NSImageView {

    func saveToDisk() {
        let rep: NSBitmapImageRep! = self.bitmapImageRepForCachingDisplay(in: self.bounds)
        self.cacheDisplay(in: self.bounds, to: rep!)

        let imageData: Data! = rep!.representation(using: NSBitmapImageRep.FileType.png, properties: [:])
        let paths = NSSearchPathForDirectoriesInDomains(.desktopDirectory, .userDomainMask, true)
        let desktopPath = URL.init(string: paths[0])
        let savePath = desktopPath?.appendingPathComponent("test.png")
        do {
            try imageData!.write(to: savePath!, options: .atomic)
        }
        catch {
            print("save error")
        }
    }

    /* Other stuff */
}

Any ideas why this would be failing? Thanks.

1

There are 1 best solutions below

0
Kevin_TA On

Thanks to Willeke's suggestion, I only had to change the way in which I was getting the path to the desktop to

let desktopPath = try! fileManager.url(for: .desktopDirectory, in: .allDomainsMask, appropriateFor: nil, create: true)

Here is the final solution

func saveToDisk() {
    let rep: NSBitmapImageRep! = self.bitmapImageRepForCachingDisplay(in: self.bounds)
    self.cacheDisplay(in: self.bounds, to: rep!)
    let imageData: Data! = rep!.representation(using: NSBitmapImageRep.FileType.png, properties: [:])

    let fileManager = FileManager.default
    let desktopPath = try! fileManager.url(for: .desktopDirectory, in: .allDomainsMask, appropriateFor: nil, create: true)            
    let filePath = desktopPath.appendingPathComponent("test.png")
    do {
        try imageData.write(to: filePath, options: .atomic)
    }
    catch {
        print("save file error: \(error)")
    }
}