Saving NSImage in Different Formats Locally

后端 未结 2 1219
梦如初夏
梦如初夏 2021-01-07 14:39

I need to allow the user to save an NSImage to a local file.

So I am using those extensions from this SO answer to can save the image in PNG Format

2条回答
  •  猫巷女王i
    2021-01-07 15:23

    You can create a custom method to allow you to specify any image type and also the directory where you would like to save your NSImage. You can also set a default value to the destination directory as the current directory, so if you don't pass the directory url it will save to the current one:

    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
            }
        }
    }
    

    You will need also to make sure the url passed to your method is a directory url. You can use URL resourceValues method to get the url isDirectoryKey value and check if it is true:

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

    You can also extend NSBitmapImageRep.FileType to provide the associated file path extension:

    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 Testing:

    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: "https://i.stack.imgur.com/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")
    }
    

提交回复
热议问题