捕获仍然没有压缩UIImage(从CMSampleBufferRef)?

我需要从CMSampleBufferRef的未压缩的图像数据获取UIImage 。 我正在使用的代码:

 captureStillImageOutput captureStillImageAsynchronouslyFromConnection:connection completionHandler:^(CMSampleBufferRef imageSampleBuffer, NSError *error) { // that famous function from Apple docs found on a lot of websites // does NOT work for still images UIImage *capturedImage = [self imageFromSampleBuffer:imageSampleBuffer]; } 

http://developer.apple.com/library/ios/#qa/qa1702/_index.html是imageFromSampleBuffer函数的链接。

但它不能正常工作。 🙁

有一个jpegStillImageNSDataRepresentation:imageSampleBuffer方法,但它提供了压缩的数据(以及因为JPEG)。

捕获静止图像后,如何使用最原始的非压缩数据创buildUIImage

也许,我应该指定一些设置video输出? 我目前正在使用这些:

 captureStillImageOutput = [[AVCaptureStillImageOutput alloc] init]; captureStillImageOutput.outputSettings = @{ (id)kCVPixelBufferPixelFormatTypeKey : @(kCVPixelFormatType_32BGRA) }; 

我注意到,该输出具有AVVideoCodecKey的默认值。 可以以任何方式避免,或者在拍摄静止图像时甚至是重要的

我在那里find了一些东西: 像“645 PRO”这样的相机的原始图像数据 ,但我只需要一个UIImage,而不使用OpenCV或OGLES或其他第三方。

imageFromSampleBuffer方法imageFromSampleBuffer工作,我使用它的改变版本,但如果我没有记错的话,你需要设置outputSettings的权利。 我认为你需要设置键为kCVPixelBufferPixelFormatTypeKey和值为kCVPixelFormatType_32BGRA

举个例子:

 NSString* key = (NSString*)kCVPixelBufferPixelFormatTypeKey; NSNumber* value = [NSNumber numberWithUnsignedInt:kCVPixelFormatType_32BGRA]; NSDictionary* outputSettings = [NSDictionary dictionaryWithObject:value forKey:key]; [newStillImageOutput setOutputSettings:outputSettings]; 

编辑

我正在使用这些设置来拍摄静止图像不是video。 你的sessionPreset AVCaptureSessionPresetPhoto? 这可能会有问题

 AVCaptureSession *newCaptureSession = [[AVCaptureSession alloc] init]; [newCaptureSession setSessionPreset:AVCaptureSessionPresetPhoto]; 

编辑2

将其保存到UIImage的部分与文档中的相同。 这就是我要问这个问题的其他原因的原因,但我想这只是抓秸秆而已。 还有另一种方式我知道,但这需要OpenCV。

 - (UIImage *) imageFromSampleBuffer:(CMSampleBufferRef) sampleBuffer{ CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer); CVPixelBufferLockBaseAddress(imageBuffer, 0); void *baseAddress = CVPixelBufferGetBaseAddress(imageBuffer); // Get the number of bytes per row for the pixel buffer size_t bytesPerRow = CVPixelBufferGetBytesPerRow(imageBuffer); // Get the pixel buffer width and height size_t width = CVPixelBufferGetWidth(imageBuffer); size_t height = CVPixelBufferGetHeight(imageBuffer); // Create a device-dependent RGB color space CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); // Create a bitmap graphics context with the sample buffer data CGContextRef context = CGBitmapContextCreate(baseAddress, width, height, 8, bytesPerRow, colorSpace, kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst); // Create a Quartz image from the pixel data in the bitmap graphics context CGImageRef quartzImage = CGBitmapContextCreateImage(context); // Unlock the pixel buffer CVPixelBufferUnlockBaseAddress(imageBuffer,0); // Free up the context and color space CGContextRelease(context); CGColorSpaceRelease(colorSpace); // Create an image object from the Quartz image UIImage *image = [UIImage imageWithCGImage:quartzImage]; // Release the Quartz image CGImageRelease(quartzImage); return (image); } 

我想这对你没有任何帮助,对不起。 我不知道你的问题的其他来源。

这是一个更有效的方法:

 UIImage *image = [UIImage imageWithData:[self imageToBuffer:sampleBuffer]]; - (NSData *) imageToBuffer:(CMSampleBufferRef)source { CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(source); CVPixelBufferLockBaseAddress(imageBuffer,0); size_t bytesPerRow = CVPixelBufferGetBytesPerRow(imageBuffer); size_t width = CVPixelBufferGetWidth(imageBuffer); size_t height = CVPixelBufferGetHeight(imageBuffer); void *src_buff = CVPixelBufferGetBaseAddress(imageBuffer); NSData *data = [NSData dataWithBytes:src_buff length:bytesPerRow * height]; CVPixelBufferUnlockBaseAddress(imageBuffer, 0); return data; }