2009-08-24 23 views
27

trong ứng dụng Cocoa của tôi, tôi tải một tệp .jpg từ đĩa, thao tác nó. Bây giờ nó cần phải được ghi vào đĩa dưới dạng tệp .png. Làm thế nào bạn có thể làm điều đó?Lưu CGImageRef vào tệp png?

Cảm ơn sự giúp đỡ của bạn!

Trả lời

13

Tạo CGImageDestination, chuyển kUTTypePNG làm loại tệp để tạo. Thêm hình ảnh, sau đó hoàn thành điểm đến.

+0

ivanceras: http://developer.apple.com/mac/library/documentation/GraphicsImaging/Reference/CGImageDestination/ Nếu bạn muốn một câu trả lời cụ thể hơn, bạn nên hỏi một câu hỏi cụ thể hơn (và bạn nên làm như vậy như một câu hỏi riêng biệt). –

+0

Chỉ cần lưu ý. Chúng ta phải thêm 'ImageIO.framework' để tham chiếu các hàm ngay cả tài liệu đang nói nó ở' ApplicationServices/ImageIO'. – Eonil

+1

@Eonil: Tùy thuộc vào nền tảng bạn đang xây dựng. Cocoa Touch không có khung ô, vì vậy khi xây dựng cho iOS, bạn cần phải liên kết trực tiếp với ImageIO. Khi xây dựng cho Mac OS X, bạn liên kết với ApplicationServices và nhận mọi thứ bên trong nó. –

89

Sử dụng CGImageDestination và chuyển qua kUTTypePNG là cách tiếp cận chính xác. Dưới đây là một đoạn nhanh:

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

Bạn sẽ cần phải thêm ImageIOCoreServices (hoặc MobileCoreServices trên iOS) để dự án của bạn và bao gồm các tiêu đề.


Nếu bạn đang ở trên iOS và không cần một giải pháp mà làm việc trên Mac quá, bạn có thể sử dụng một cách tiếp cận đơn giản hơn:

// `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]; 

Trong các thử nghiệm của tôi, cách tiếp cận ImageIO sắp Nhanh hơn 10% so với cách tiếp cận UIImage trên iPhone 5s của tôi. Trong giả lập, cách tiếp cận UIImage nhanh hơn. Nó có thể là giá trị thử nghiệm cho từng tình huống cụ thể của bạn trên thiết bị nếu bạn đang thực sự quan tâm đến hiệu suất.

+0

Bạn có bất kỳ chi tiết nào trong số này có hiệu quả hơn không - cả về thời gian và bộ nhớ? Cảm ơn bạn. –

+0

Cập nhật câu trả lời của tôi với thông tin hiệu suất :) –

16

Đây là một hệ điều hành MacOS thân thiện, Swift 3 & 4 Ví dụ:

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