Saving Cgimageref to a Png File

Saving CGImageRef to a png file?

Create a CGImageDestination, passing kUTTypePNG as the type of file to create. Add the image, then finalize the destination.

iOS: writing a CGImageRef disk in png or jpeg

Using UIKit, the code becomes a simple 3-liner:

UIImage *uiImage = [UIImage imageWithCGImage:cgImage];
NSData *jpgData = UIImageJPEGRepresentation(uiImage, 0.9f);
[jpgData writeToFile:path atomically:NO];

How to write CGImageRef to png file. CGImageDestinationCreateWithURL returns nil

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

You have to add ImageIO and MobileCoreServices to your project and also have to add header.

Save CGImageRef as PNG-8

Hmm, no answers :) I believe the solution may be to use libpng but I haven't tried it yet. I'll mark this as the accepted answer for now, but if anyone can offer a good tip I'll gladly change it over!

Thanks.

Edit:

I ended up hacking apart https://github.com/pornel/pngquant to get it to accept CGImageRefs, and save PNG-8 files. It wasn't pretty. In the end, I actually switched to GIF (kUTTypeGIF) which ran a lot faster in my tests.

Save CGImageRef to PNG file errors? (ARC Caused?)

The code you posted wouldn't work either with or without ARC, because you need to expand the tilde in the path name before passing it.

The code you posted also was leaking the items returned by CGDisplayCreateImage and CGImageDestinationCreateWithURL. Here's an example that works and doesn't leak:

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
CGDirectDisplayID displayID = CGMainDisplayID();
CGImageRef imageRef = CGDisplayCreateImage(displayID); //this is a screenshot (works fine)

NSString *path = [@"~/Desktop/public.png" stringByExpandingTildeInPath];
[self savePNGImage:imageRef path:path];

CFRelease(imageRef);
}

- (void)savePNGImage:(CGImageRef)imageRef path:(NSString *)path
{
NSURL *fileURL = [NSURL fileURLWithPath:path];
CGImageDestinationRef dr = CGImageDestinationCreateWithURL((__bridge CFURLRef)fileURL, kUTTypePNG , 1, NULL);

CGImageDestinationAddImage(dr, imageRef, NULL);
CGImageDestinationFinalize(dr);

CFRelease(dr);
}

SWIFT 3 - CGImage to PNG

Thanks the issue of DonMag in my other question SWIFT 3 - CGImage copy always nil, here is the code to solve this :

func saveImageWithAlpha(theImage: UIImage, destFile: URL) -> Void {

// odd but works... solution to image not saving with proper alpha channel
UIGraphicsBeginImageContext(theImage.size)
theImage.draw(at: CGPoint.zero)
let saveImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()

if let img = saveImage, let data = UIImagePNGRepresentation(img) {

try? data.write(to: destFile)

}

}

How exactly to make a CGImageRef from an image on disk

gcamp is more or less correct, you are pretty safe to use this on a background thread, but to answer your question, I believe the following would work.

CGDataProviderRef dataProvider = CGDataProviderCreateWithFilename("file");
CGImageRef image = CGImageCreateWithPNGDataProvider(dataProvider, NULL, NO, kCGRenderingIntentDefault);

There is also a function for jpg images, CGImageCreateWithJPEGDataProvider.

(be sure to release the data provider and image when done)

How to save CGImage to Data in Swift?

The problem is the way you are creating your mutable data. Data is not convertible to NSMutableData. Just change your forced casting from Data to CFMutableData to CFDataCreateMutable(nil, 0). Another option is to use NSMutableData which is toll-free bridged to CFMutableData. Try like this:

if let cgi = cgi, 
let mutableData = CFDataCreateMutable(nil, 0),
let destination = CGImageDestinationCreateWithData(mutableData, "public.png" as CFString, 1, nil) {
CGImageDestinationAddImage(destination, cgi, nil)
if CGImageDestinationFinalize(destination) {
let data = mutableData as Data
if let image = UIImage(data: data) {
print(image.size)
}
} else {
print("Error writing Image")
}
}

edit/update: Xcode 11 • Swift 5.1

extension CGImage {
var png: Data? {
guard let mutableData = CFDataCreateMutable(nil, 0),
let destination = CGImageDestinationCreateWithData(mutableData, "public.png" as CFString, 1, nil) else { return nil }
CGImageDestinationAddImage(destination, self, nil)
guard CGImageDestinationFinalize(destination) else { return nil }
return mutableData as Data
}
}


Related Topics



Leave a reply



Submit