【发布时间】:2010-11-22 04:50:47
【问题描述】:
在我的 Cocoa 应用程序中,我从磁盘加载一个 .jpg 文件并对其进行操作。现在需要将其作为 .png 文件写入磁盘。你怎么能这样做?
感谢您的帮助!
【问题讨论】:
标签: swift objective-c cocoa core-graphics cgimage
在我的 Cocoa 应用程序中,我从磁盘加载一个 .jpg 文件并对其进行操作。现在需要将其作为 .png 文件写入磁盘。你怎么能这样做?
感谢您的帮助!
【问题讨论】:
标签: swift objective-c cocoa core-graphics cgimage
Swift 5+ 采用的版本
import Foundation
import CoreGraphics
import CoreImage
import ImageIO
import MobileCoreServices
extension CIImage {
public func convertToCGImage() -> CGImage? {
let context = CIContext(options: nil)
if let cgImage = context.createCGImage(self, from: self.extent) {
return cgImage
}
return nil
}
public func data() -> Data? {
convertToCGImage()?.pngData()
}
}
extension CGImage {
public func pngData() -> Data? {
let cfdata: CFMutableData = CFDataCreateMutable(nil, 0)
if let destination = CGImageDestinationCreateWithData(cfdata, kUTTypePNG as CFString, 1, nil) {
CGImageDestinationAddImage(destination, self, nil)
if CGImageDestinationFinalize(destination) {
return cfdata as Data
}
}
return nil
}
}
【讨论】:
这是一个适用于 macOS 的 Swift 3 和 4 示例:
@discardableResult func writeCGImage(_ image: CGImage, to destinationURL: URL) -> Bool {
guard let destination = CGImageDestinationCreateWithURL(destinationURL as CFURL, kUTTypePNG, 1, nil) else { return false }
CGImageDestinationAddImage(destination, image, nil)
return CGImageDestinationFinalize(destination)
}
【讨论】:
使用CGImageDestination 并传递kUTTypePNG 是正确的方法。这是一个快速的 sn-p:
@import MobileCoreServices; // or `@import CoreServices;` on Mac
@import ImageIO;
BOOL CGImageWriteToFile(CGImageRef image, NSString *path) {
CFURLRef url = (__bridge CFURLRef)[NSURL fileURLWithPath:path];
CGImageDestinationRef destination = CGImageDestinationCreateWithURL(url, kUTTypePNG, 1, NULL);
if (!destination) {
NSLog(@"Failed to create CGImageDestination for %@", path);
return NO;
}
CGImageDestinationAddImage(destination, image, nil);
if (!CGImageDestinationFinalize(destination)) {
NSLog(@"Failed to write image to %@", path);
CFRelease(destination);
return NO;
}
CFRelease(destination);
return YES;
}
您需要将ImageIO 和CoreServices(或iOS 上的MobileCoreServices)添加到您的项目并包含标题。
如果您使用的是 iOS 并且不需要也适用于 Mac 的解决方案,则可以使用更简单的方法:
// `image` is a CGImageRef
// `path` is a NSString with the path to where you want to save it
[UIImagePNGRepresentation([UIImage imageWithCGImage:image]) writeToFile:path atomically:YES];
在我的测试中,ImageIO 方法比我的 iPhone 5s 上的 UIImage 方法快了大约 10%。在模拟器中,UIImage 方法更快。如果您真的关心性能,可能值得针对您在设备上的特定情况进行测试。
【讨论】:
创建一个CGImageDestination,传递kUTTypePNG 作为要创建的文件类型。添加图片,然后确定目的地。
【讨论】:
ImageIO.framework 来引用函数,即使文档说它位于ApplicationServices/ImageIO。