I’m having some problems getting a UIImage from a CVPixelBuffer. This is what I am trying:
CVPixelBufferRef pixelBuffer = CMSampleBufferGetImageBuffer(imageDataSampleBuffer);
CFDictionaryRef attachments = CMCopyDictionaryOfAttachments(kCFAllocatorDefault, imageDataSampleBuffer, kCMAttachmentMode_ShouldPropagate);
CIImage *ciImage = [[CIImage alloc] initWithCVPixelBuffer:pixelBuffer options:(NSDictionary *)attachments];
if (attachments)
CFRelease(attachments);
size_t width = CVPixelBufferGetWidth(pixelBuffer);
size_t height = CVPixelBufferGetHeight(pixelBuffer);
if (width && height) { // test to make sure we have valid dimensions
UIImage *image = [[UIImage alloc] initWithCIImage:ciImage];
UIImageView *lv = [[UIImageView alloc] initWithFrame:self.view.frame];
lv.contentMode = UIViewContentModeScaleAspectFill;
self.lockedView = lv;
[lv release];
self.lockedView.image = image;
[image release];
}
[ciImage release];
height and width are both correctly set to the resolution of the camera. image is created but I it seems to be black (or maybe transparent?). I can’t quite understand where the problem is. Any ideas would be appreciated.
First of all the obvious stuff that doesn’t relate directly to your question:
AVCaptureVideoPreviewLayeris the cheapest way to pipe video from either of the cameras into an independent view if that’s where the data is coming from and you’ve no immediate plans to modify it. You don’t have to do any pushing yourself, the preview layer is directly connected to theAVCaptureSessionand updates itself.I have to admit to lacking confidence about the central question. There’s a semantic difference between a
CIImageand the other two types of image — aCIImageis a recipe for an image and is not necessarily backed by pixels. It can be something like “take the pixels from here, transform like this, apply this filter, transform like this, merge with this other image, apply this filter”. The system doesn’t know what aCIImagelooks like until you chose to render it. It also doesn’t inherently know the appropriate bounds in which to rasterise it.UIImagepurports merely to wrap aCIImage. It doesn’t convert it to pixels. PresumablyUIImageViewshould achieve that, but if so then I can’t seem to find where you’d supply the appropriate output rectangle.I’ve had success just dodging around the issue with:
With gives an obvious opportunity to specify the output rectangle. I’m sure there’s a route through without using a
CGImageas an intermediary so please don’t assume this solution is best practice.