【问题标题】:UIImage uncompressed from AVCaptureStillImageOutput从 AVCaptureStillImageOutput 解压缩的 UIImage
【发布时间】:2016-08-24 10:18:12
【问题描述】:

这是我迄今为止尝试的相机配置:

    AVCaptureSession *session = [[AVCaptureSession alloc] init];
    [session setSessionPreset:AVCaptureSessionPresetInputPriority];

    AVCaptureDevice *videoDevice = [AVCamViewController deviceWithMediaType:AVMediaTypeVideo preferringPosition:AVCaptureDevicePositionBack];

    NSError *errorVideo;

    AVCaptureDeviceFormat *deviceFormat = nil;
    for (AVCaptureDeviceFormat *format in videoDevice.formats) {
        CMVideoDimensions dim = CMVideoFormatDescriptionGetDimensions(format.formatDescription);

        if (dim.width == 2592 && dim.height == 1936) {
            deviceFormat = format;
            break;
        }
    }

    [videoDevice lockForConfiguration:&errorVideo];
    if (deviceFormat) {
        videoDevice.activeFormat = deviceFormat;

        if ([videoDevice isExposureModeSupported:AVCaptureExposureModeContinuousAutoExposure]) {
            [videoDevice setExposureMode:AVCaptureExposureModeContinuousAutoExposure];
        }

        if ([videoDevice isAutoFocusRangeRestrictionSupported]) {
            [videoDevice setAutoFocusRangeRestriction:AVCaptureAutoFocusRangeRestrictionFar];
        }
    }
    [videoDevice unlockForConfiguration];

    AVCaptureDeviceInput *videoDeviceInput = [AVCaptureDeviceInput deviceInputWithDevice:videoDevice error:&error];

    if ([session canAddInput:videoDeviceInput]) {
        [session addInput:videoDeviceInput];
    }

    AVCaptureStillImageOutput *stillImageOutput = [[AVCaptureStillImageOutput alloc] init];

    if ([session canAddOutput:stillImageOutput]) {
        [stillImageOutput setOutputSettings:@{(id)kCVPixelBufferPixelFormatTypeKey:@(kCVPixelFormatType_32BGRA)}];
        [session addOutput:stillImageOutput];
    }

这是我尝试从 CMSamplebuffer 获取 UIImage 的方法:

 [[self stillImageOutput] captureStillImageAsynchronouslyFromConnection:connection completionHandler:^(CMSampleBufferRef imageDataSampleBuffer, NSError *error) {

        if (imageDataSampleBuffer && !error) {
            dispatch_async(dispatch_get_main_queue(), ^{
                UIImage *image = [self imageFromSampleBuffer:imageDataSampleBuffer];
            });
        }
    }];

这是一个 Apple 示例代码:

- (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);
}

但图像始终为零。 做了一些调试后。我发现这个函数总是返回 nil CMSampleBufferGetImageBuffer(sampleBuffer);

有人可以帮忙吗?

【问题讨论】:

  • 你确定你所有的输入和东西都正确设置了吗?
  • 添加了包含所有配置的精简版代码。用于相机和输出

标签: ios uiimage avfoundation ios-camera core-video


【解决方案1】:

这是因为 CMSampleBufferRef 必须立即处理,因为它被快速有效地释放。

这是我生成图像的代码:

 let connection = imageFileOutput.connectionWithMediaType(AVMediaTypeVideo)

if  connection != nil {
    imageFileOutput.captureStillImageAsynchronouslyFromConnection(connection) { [weak self] (buffer, err) -> Void in
        if CMSampleBufferIsValid(buffer) {
            let imageDataJpeg = self?.imageFromSampleBuffer(buffer)
        } else {
            print(err)
        }
    }
}

如您所见,我在此功能的范围内将其转换为图像。一旦它是图像,我将其发送出去进行处理。

【讨论】:

  • 请将 jpegstillimagensdatarepresentation 更改为我提供的方法。我知道这无关紧要,但对于后代来说可能是。我在未压缩的标题中特别难过。再次感谢!
  • 当您说未压缩时,您的意思是您想要最高分辨率吗?如果是这样,您可以将会话上的预设更改为 AVCaptureSessionPresetPhoto?
  • Apple Docs: "在 iOS 上,目前唯一支持的键是 AVVideoCodecKey 和 kCVPixelBufferPixelFormatTypeKey。这些键是互斥的,只能存在一个。推荐的值为 AVVideoCodecKey 的 kCMVideoCodecType_JPEG 和 kCVPixelFormatType_420YpCbCr8BiPlanarFullRange 和kCVPixelFormatType_32BGRA 用于 kCVPixelBufferPixelFormatTypeKey。” 如果想要使用原始 sampleBuffer 而不是 JPEG 编码的 sampleBuffer,则应该使用 kCVPixelBufferPixelFormatTypeKey。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-10-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-29
  • 1970-01-01
相关资源
最近更新 更多