优化iPhone拍照速度,UIImagePickerController

问题描述:

我在我的应用程序中使用UIImagePickerController。有没有人使用任何优化技巧拍摄延迟?我不需要将它们存储到图书馆。我只是想要捕捉像素数据并在计算后摧毁图像对象。优化iPhone拍照速度,UIImagePickerController

另外,有没有办法隐藏镜头时,它加载?

(最坏的情况,我可能会掩盖在相机启动时镜头和保存时/计算掩盖冻结的图像。)

编辑:我已经设置showsCameraControls = NO;。这隐藏了快照之间的镜头效果,但不会影响相机启动时镜头动画的存在。

你是否已经使用了UIImagePickerController?从iOS 4开始,AVFoundation允许您以任何支持的视频分辨率接收来自相机的实时图像流,而无需指定的用户界面,因此没有镜头效果,并且在iPhone 4上,您可以拍摄高达720p的图像,而无需潜伏;在早期的设备上,你可以获得一个480p。

可从here获得的WWDC 2010视频的第409部分是一个很好的开始。您需要创建一个AVCaptureSession,通过AVCaptureDeviceInput附加一个合适的AVCaptureDevice,添加一个AVCaptureVideoDataOutput并为其提供一个将数据传输给您的调度队列。你将得到一个CVImageBufferRef,它直接暴露原始像素数据。

编辑:苹果的示例代码看似是失踪,我倾向于使用大约如下:

AVCaptureSession *session; 
AVCaptureDevice *device; 
AVCaptureVideoDataOutput *output; 

// create a capture session 
session = [[AVCaptureSession alloc] init]; 
session.sessionPreset = ...frame quality you want...; 

// grab the default video device (which will be the back camera on a device 
// with two), create an input for it to the capture session 
NSError *error = nil; 
device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; 
AVCaptureDeviceInput *input = [AVCaptureDeviceInput 
            deviceInputWithDevice:device error:&error]; 

// connect the two 
[session addInput:input]; 

// create an object to route output back here 
output = [[AVCaptureVideoDataOutput alloc] init]; 
[session addOutput:output]; 

// create a suitable dispatch queue, GCD style, and hook 
// self up as the delegate 
dispatch_queue_t queue = dispatch_queue_create(NULL, NULL); 
[output setSampleBufferDelegate:self queue:queue]; 
dispatch_release(queue); 

// set 32bpp BGRA pixel format 
output.videoSettings = 
     [NSDictionary 
      dictionaryWithObject: 
          [NSNumber numberWithInt:kCVPixelFormatType_32BGRA] 
      forKey:(id)kCVPixelBufferPixelFormatTypeKey]; 

[session startRunning]; 

这会然后开始交付CMSampleBuffers您captureOutput:didOutputSampleBuffer:fromConnection:您创建的调度队列(即单独的线程)。显然,生产代码比上面的要有更多的理智和结果检查。

以下代码示例需要一个包含视频帧的传入CMSampleBuffer,并将其转换为CGImage,然后将其发送到主线程,其中,在我的测试代码中,将其转换为UIImage并设置为内部的东西一个UIImageView,证明整个事情是工作:

CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer); 

// lock momentarily, to get enough details to create a CGImage in the future... 
CVPixelBufferLockBaseAddress(imageBuffer, 0); 
    void *baseAddress = CVPixelBufferGetBaseAddress(imageBuffer); 
    size_t bytesPerRow = CVPixelBufferGetBytesPerRow(imageBuffer); 
    size_t width = CVPixelBufferGetWidth(imageBuffer); 
    size_t height = CVPixelBufferGetHeight(imageBuffer); 

CVPixelBufferUnlockBaseAddress(imageBuffer, 0); 

// create a CGImageRef 
CGColorSpaceRef colourSpace = CGColorSpaceCreateDeviceRGB(); 
CGContextRef contextRef = 
    CGBitmapContextCreate(baseAddress, width, height, 8, bytesPerRow, colourSpace, kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst); 
CGImageRef imageRef = CGBitmapContextCreateImage(contextRef); 
CGContextRelease(contextRef); 
CGColorSpaceRelease(colourSpace); 

[self performSelectorOnMainThread:@selector(postCGImage:) withObject:[NSValue valueWithPointer:imageRef] waitUntilDone:YES]; 
CGImageRelease(imageRef); 

我混为一谈,我正常使用接收视频帧,例如从着想视图控制器一些东西的对象;希望我没有犯任何错误。

+0

你赢了,汤米。我开始认为我不得不做一些不雅的掩盖,并从令人讨厌的延迟中分散用户的注意力。谢谢! – 2011-03-03 00:18:56

+0

好奇。所涉及的源代码;我在iOS Reference Library中找不到它。是否必须成为WWDC与会者才能访问所有这些示例项目? – 2011-03-03 01:13:40

+0

我不这么认为;我猜这只是苹果三年一度的重新排列重新排列的又一次犯规。我会用一些示例的东西来编辑我的答案... – Tommy 2011-03-03 12:08:10