如何在不使用jpeg编码器的情况下从AVCaptureSession获取全分辨率图像?

时间:2015-05-26 23:55:52

标签: ios image avcapturesession

我试图从相机中保存全分辨率的tiff文件。我在这里看到了许多非常有用的指南,用于捕获直接像素数据中的静态图像或使用jpeg硬件压缩器。到目前为止,我能够以BGRA格式捕获直接像素数据,但我似乎无法在5秒内获得大于1920x1080的样本缓冲区。当我切换到jpeg压缩器路径时,我得到完整的5MP图像..只是以jpeg格式。

这是我的设置:

// Create the AVCaptureSession
AVCaptureSession *session = [[AVCaptureSession alloc] init];
[self.session setSessionPreset:AVCaptureSessionPresetPhoto];

以及稍后的输出设置:

NSDictionary *outputSettings = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithUnsignedInt:kCVPixelFormatType_32BGRA], (id)kCVPixelBufferPixelFormatTypeKey,nil];

或者:

[stillImageOutput setOutputSettings:@{AVVideoCodecKey : AVVideoCodecJPEG}];

在我要求我设置的样本缓冲区之前:

setHighResolutionStillImageOutputEnabled:YES

然后我使用: -captureStillImageAsynchronouslyFromConnection 获取样本缓冲区。

刚刚结束...... 在-captureStillImageAsynchronouslyFromConnection:的完成区域内 对于Jpegs我使用:

NSData *imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageDataSampleBuffer];

对于BGRA,我使用:

CFDictionaryRef metadata = CMCopyDictionaryOfAttachments(kCFAllocatorDefault, imageDataSampleBuffer, kCMAttachmentMode_ShouldPropagate);
CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(imageDataSampleBuffer);
// >>>>>>>>>> lock buffer address
CVPixelBufferLockBaseAddress(imageBuffer, 0);


//Get information about the image
uint8_t *baseAddress = (uint8_t *)CVPixelBufferGetBaseAddress(imageBuffer);
size_t bytesPerRow = CVPixelBufferGetBytesPerRow(imageBuffer);
size_t width = CVPixelBufferGetWidth(imageBuffer);
size_t height = CVPixelBufferGetHeight(imageBuffer);

// create suitable color space
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();

//Create suitable context (suitable for camera output setting kCVPixelFormatType_32BGRA)
CGContextRef newContext = CGBitmapContextCreate(baseAddress, width, height, 8, bytesPerRow, colorSpace, kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst);

// <<<<<<<<<< unlock buffer address
CVPixelBufferUnlockBaseAddress(imageBuffer, 0);

// release color space
CGColorSpaceRelease(colorSpace);

//Create a CGImageRef from the CVImageBufferRef
CGImageRef newImage = CGBitmapContextCreateImage(newContext);

我忽略了什么吗?管道中的所有内容似乎都有效,我无法在Apple文档中找到任何额外的设置。是否有更好/不同的方法来做到这一点?

TDLR:使用BGRA像素格式输出设置,我似乎无法从静态图像捕捉会话中获得超过1920x1080的效果。希望有人能指出我正确的方向。

1 个答案:

答案 0 :(得分:0)

糟糕!我设置类var而不是本地类,并稍后覆盖类var,因此不使用会话预设。

代码应该是:

    // Create the AVCaptureSession
AVCaptureSession *session = [[AVCaptureSession alloc] init];
[session setSessionPreset:AVCaptureSessionPresetPhoto];

超级简单的错误。