views:

703

answers:

2

Hi there. I am using the following code to save a frame of a movie to my desktop:

NSCIImageRep *imageRep = [NSCIImageRep imageRepWithCIImage:[CIImage imageWithCVImageBuffer:imageBuffer]];
NSImage *image = [[[NSImage alloc] initWithSize:[imageRep size]] autorelease];
[image addRepresentation:imageRep];
CVBufferRelease(imageBuffer);

NSArray *representations = [image representations];
NSData *bitmapData = [NSBitmapImageRep representationOfImageRepsInArray:representations usingType:NSJPEGFileType properties:nil];
[bitmapData writeToFile:@"/Users/ricky/Desktop/MyImage.jpeg" atomically:YES];

At the second last line of code, I receive the following messages in the console, with no result being saved to the desktop:

<Error>: CGImageDestinationFinalize image destination does not have enough images
CGImageDestinationFinalize failed for output type 'public.jpeg'

The NSImage is still an allocated object for the entire method call, so I'm not sure why I am receiving complaints about insufficient amount of images.

I'd appreciate any help. Thanks in advance, Ricky.

+1  A: 

I'm sorry i don't really know why your code doesn't work, but approaching it a different way (and i think more efficiently than your CVImageBuffer to CIImage to NSCIImageRep to NSImage to NSData, albeit at a slightly lower level):-

  1. CVImageBuffer to CGImage
  2. CGImage to jpg file

I don't have code ready made to do this but extracting the right stuff from those examples should be straight forward.

+1  A: 

I think the source of the problem is that you're passing an array of NSCIImageRep objects to representationOfImageRepsInArray:usingType:properties:, which I believe expects an array of NSBitmapImageRep objects.

What you want to do is create an NSBitmapImageRep from your CIImage. Then you can use that to write to disk. That would be roughly:

CIImage *myImage = [CIImage imageWithCVImageBuffer:imageBuffer]; 
NSBitmapImageRep *bitmapRep = [[NSBitmapImageRep alloc] initWithCIImage:myImage];
NSData *jpegData [bitmapRep representationUsingType:NSJPEGFileType properties:nil];
[jpegData writeToFile:@"/Users/ricky/Desktop/MyImage.jpeg" atomically:YES];

Of course, you'd want to handle any error cases and probably pass a properties dictionary to fine-tune the JPEG creation.

Jess Bowers
Thanks a lot Jess. You're solution worked great. jib, thanks for your post as well.While we're here, does anyone know if there's a way to horizontally flip the image before we save it to disk?Thanks again.Ricky.
Ricky