在调用jpegStillImageNSDataRepresentation之前在jpegStillImageNSDataRepresentation中返回裁剪图像缓冲区

时间:2015-04-19 11:31:06

标签: ios avfoundation

我正在写一个相机应用程序。以下是我拍摄静止图像的代码:

[_stillImageOutput captureStillImageAsynchronouslyFromConnection:connection completionHandler:^(CMSampleBufferRef imageDataSampleBuffer, NSError *error) {
    NSData *imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageDataSampleBuffer];
    UIImage *originalImage = [UIImage imageWithData:imageData];
    UIImage *croppedImage  = [self cropImage:originalImage];
    [self.delegate cameraVC:self didCaptureImage:croppedImage];
}];

[self cropImage:]中的主要代码是:

UIGraphicsBeginImageContextWithOptions(cropSize, YES, 1);    
CGRect thumbnailRect = CGRectZero;
thumbnailRect.origin = thumbnailPoint;
thumbnailRect.size.width  = scaledWidth;
thumbnailRect.size.height = scaledHeight;

[image drawInRect:thumbnailRect];
newImage = UIGraphicsGetImageFromCurrentImageContext();

UIGraphicsEndImageContext();

然而,事实证明这样的cropImage功能非常慢。事实上,我尝试了几种应用于originalImage的裁剪方法,它们都很慢。

因此,我在考虑是否可以在调用

之前修改返回的imageDataSampleBuffer
[AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageDataSampleBuffer]

这样生成的jpeg数据已经是正确裁剪的图像。

感谢任何帮助。

1 个答案:

答案 0 :(得分:0)

UIGraphics功能是线程安全的,因此您可以使用GDC或在与主要不同的线程上轻松地在不同的队列上执行裁剪。
可能很慢,因为捕获的图像非常大。
这里有一些你可以申请的解决方案:

  1. 在其他队列中使用裁剪功能,使用其中一个GDC低优先级队列将呼叫包裹在dispatch_async
  2. 将图片转换为CIImage并应用CIFilter来裁剪它。注意您需要创建CIContext。这是一项密集型操作,但是一旦创建了一个,您就不需要创建另一个。可以使用GPU或CPU创建上下文,选择取决于不同的规格,我认为GPU可以满足您的需求。此外,有一种很好的方法可以将CVPixelBufferRef转换为CIImageCVPixelBufferRef内包含CMSampleBufferRef
  3. 在iOS8中,Apple推出了新的API,将CVPixelBufferRef直接转换为vImage_Buffer,加速框架包含有效的方法,可以快速对图像进行线程安全操作,同时裁剪
    如果您正在考虑从CVPixelBufferRef获取图像,请注意图像方向。