优化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);
我混为一谈,我正常使用接收视频帧,例如从着想视图控制器一些东西的对象;希望我没有犯任何错误。
你赢了,汤米。我开始认为我不得不做一些不雅的掩盖,并从令人讨厌的延迟中分散用户的注意力。谢谢! – 2011-03-03 00:18:56
好奇。所涉及的源代码;我在iOS Reference Library中找不到它。是否必须成为WWDC与会者才能访问所有这些示例项目? – 2011-03-03 01:13:40
我不这么认为;我猜这只是苹果三年一度的重新排列重新排列的又一次犯规。我会用一些示例的东西来编辑我的答案... – Tommy 2011-03-03 12:08:10