在我的 Cocoa 应用程序中,我从磁盘加载一个 .jpg 文件并对其进行操作。现在需要将其作为 .png 文件写入磁盘。你怎么能那样做?
谢谢你的帮助!
在我的 Cocoa 应用程序中,我从磁盘加载一个 .jpg 文件并对其进行操作。现在需要将其作为 .png 文件写入磁盘。你怎么能那样做?
谢谢你的帮助!
使用CGImageDestination
和传递kUTTypePNG
是正确的方法。这是一个快速的片段:
@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
(或MobileCoreServices
在 iOS 上)并包含标题。
如果您使用的是 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 方法更快。如果您真的关心性能,可能值得针对您在设备上的特定情况进行测试。
这是一个 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
作为要创建的文件类型传递。添加图像,然后确定目的地。
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
}
}