如何在Swift中将NSImage写入JPEG文件?

时间:2016-01-25 21:55:09

标签: swift cocoa nsimage

一个迅速的问题。不是Obj-C问题。 请勿将其标记为重复

我正在尝试编写一个在OS X上生成JPEG缩略图的类。我希望我有一些明智的东西形成缩小的NSImage,但我很难将JPEG文件写入磁盘

class ImageThumbnail {
    let size = CGSize(width: 128, height: 128)
    var originalPath = ""

    init(originalPath: String){
        self.originalPath = originalPath
    }

    func generateThumbnail() {
        let url = NSURL(fileURLWithPath: originalPath)

        if let imageSource = CGImageSourceCreateWithURL(url, nil) {
            let options: [NSString: NSObject] = [
                kCGImageSourceThumbnailMaxPixelSize: max(size.width, size.height) / 2.0,
                kCGImageSourceCreateThumbnailFromImageAlways: true
            ]

            let cgImage = CGImageSourceCreateThumbnailAtIndex(imageSource, 0, options)
            let scaledImage = cgImage.flatMap { NSImage(CGImage: $0, size: size) }

            // How do I write scaledImage to a JPEG file?
        }
    }
}

使用示例:ImageThumbail(originalPath: "/path/to/original").generateThumbnail()

3 个答案:

答案 0 :(得分:6)

首先,您需要获取图像的位图表示,获取该图像的JPEG表示(或您想要的任何格式),然后将二进制数据写入文件:

if let bits = scaledImage?.representations.first as? NSBitmapImageRep {
    let data = bits.representationUsingType(.NSJPEGFileType, properties: [:])
    data?.writeToFile("/path/myImage.jpg", atomically: false)
}

NSBitmapImageFileType为您提供了一种表示形式选择:

public enum NSBitmapImageFileType : UInt {

    case NSTIFFFileType
    case NSBMPFileType
    case NSGIFFileType
    case NSJPEGFileType
    case NSPNGFileType
    case NSJPEG2000FileType
}

答案 1 :(得分:1)

似乎在Swift 3中NSCGImageSnapshotRep不再转换为NSBitmapImageRep,或者这仅适用于某些图像(我不知道哪个是真的,因为我只遇到了 转换为NSBitmapImageRep。

another answer的这种轻微改动对我来说在Xcode 8中的Swift 3 + macOS Sierra SDK中起作用:

let cgImage = img.cgImage(forProposedRect: nil, context: nil, hints: nil)!
let bitmapRep = NSBitmapImageRep(cgImage: cgImage)
let jpegData = bitmapRep.representation(using: NSBitmapImageFileType.JPEG, properties: [:])!

(请原谅强制解包,只是为了简洁 - 绝对是检查生产代码的选项,因为目前的SDK已经在这里引入了选项。)

答案 2 :(得分:0)

extension NSImage {
    func imagePNGRepresentation() -> NSData? {
        if let imageTiffData = self.tiffRepresentation, let imageRep = NSBitmapImageRep(data: imageTiffData) {
            // let imageProps = [NSImageCompressionFactor: 0.9] // Tiff/Jpeg
            // let imageProps = [NSImageInterlaced: NSNumber(value: true)] // PNG
            let imageProps: [String: Any] = [:]
            let imageData = imageRep.representation(using: NSBitmapImageFileType.PNG, properties: imageProps) as NSData?
            return imageData
        }
        return nil
    }
}

if let thumbImageData = thumbimage.imagePNGRepresentation() {
    thumbImageData.write(toFile: "/path/to/thumb.png", atomically: false)
}