捕获仍然没有压缩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; }