cameraOverlayView属性。但是遇到了问题,当iPad旋转后,自定义的视图也会跟着旋转,但是iPhone上就没有问题。尝试子类化UIImagePickerController的- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation方法却没有被调用,很是奇怪,原来官方文档说:“
Important The UIImagePickerController
我就无语了。既然让自定义视图,为啥旋转得不到响应。
最终得知定制视图还可以通过另一种方式AVFoundation。这个框架比较底层,更加灵活。所以对此进行了学习,通过不懈努力,终于实现了自己的需求。
现在把使用AVFoundation捕捉静态图片做个简单的的介绍:
先来看下AVCaptureSession的工作原理: AVCaptureSession是用来协调控制捕捉设备和输出数据的一个类。
捕捉图像至少需要一下几个对象:
1 AVCaptureDevice:是输入设备的抽象,比如摄像机、麦克风
2 AVCaptureInput:用来配置输入设备
3 AVCaptureOutput:用来管理输出视频文件或者静态图像
4 AVCaptureSession:协调数据从输入设备到输出对象
如果想从摄像头捕捉一张静态图像,那么需要完成一下几个步骤:
- Create an
AVCaptureSession
object to coordinate the flow of data from an AV input device to an output
(创建AVCaptureSession)对象 - Find the
AVCaptureDevice
object for the input type you want
(获取输入设备) - Create an
AVCaptureDeviceInput
object for the device
(为输入设备创建AVCaptureDeviceInput对象
) - Create an
AVCaptureVideoDataOutput
object to produce video frames
(创建输出对象用来产生视频帧) - Implement a delegate for the
AVCaptureVideoDataOutput
object to process video frames
(完成输出协议,处理视频帧) - Implement a function to convert the CMSampleBuffer received by the delegate into a
UIImage
object (完成方法实现CMSampleBuffer到UIImage的转换)
下面是对应具体实现:
/*创建并配置 Session*/
AVCaptureSession *session = [[AVCaptureSession alloc] init];
session.sessionPreset = AVCaptureSessionPresetMedium;
/*创建并配置输入设备*/
AVCaptureDevice *device =
[AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
NSError *error = nil;
AVCaptureDeviceInput *input =
[AVCaptureDeviceInput deviceInputWithDevice:device error:&error];
if (!input) {
// Handle the error appropriately.
}
[session addInput:input];
/*创建输出对象*/
AVCaptureVideoDataOutput *output = [[[AVCaptureVideoDataOutput alloc] init] autorelease];
[session addOutput:output];
output.videoSettings =
[NSDictionary dictionaryWithObject:[NSNumber numberWithInt:kCVPixelFormatType_32BGRA]
forKey:(id)kCVPixelBufferPixelFormatTypeKey];
output.minFrameDuration = CMTimeMake(1, 15);
dispatch_queue_t queue = dispatch_queue_create("MyQueue", NULL);
[output setSampleBufferDelegate:self queue:queue];
dispatch_release(queue);
/*完成协议*/
- (void)captureOutput:(AVCaptureOutput *)captureOutput
didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer
fromConnection:(AVCaptureConnection *)connection {
* pool = [[NSAutoreleasePoolalloc] init];
UIImage *image = imageFromSampleBuffer(sampleBuffer);
// Add your code here that uses the image.
drain];
}
/*开始不抓捕*/
[session startRunning];
需要注意的是:创建输出对象的时候,要设定委托对象,并且要在一个新创建的运行队列里,所以使用了 dispatch_queue_t。协议回调的时候是运行在这个队列中的,所以在协议处理函数中要增加内存池。
以上就是基本的用法,下面贴出我根据书上的一个例子改装的Demo。实现过程中遇到了问题,就是屏幕旋转的时候,实时画面反转错误。所以在旋转的时候,要更改
AVCaptureVideoPreviewLayer的方向。还是看代码吧!
https://github.com/cokecoffe/ios-demo/tree/master/CameraWithAVFoudation