从这一节开始,我们使用AV Foundation制作一个条码(不仅仅是二维码)扫描程序,除了扫描二维码功能外,还具备语音合成和摄像头缩放功能。
源码地址:https://code.csdn.net/yamingwu/collqr/tree/master
创建名为ColloQR的单view应用程序。打开storyboard,禁用sized class。选中view controller,通过editor菜单将其放入navigation controller中。最后修改标题为ColloQR:
使用摄像头
打开ViewController.m,添加import:
@import AVFoundation;
在实现中定义以下实例变量:
@implementation ViewController {
AVCaptureSession *_captureSession;
AVCaptureDevice *_videoDevice;
AVCaptureDeviceInput * _videoInput;
AVCaptureVideoPreviewLayer *_previewLayer;
BOOL _running;
}
AVCaptureSession:AVFoundation中的核心类,用于通过硬件获取、处理和输出视频。一个Capture Session由多个输入和多个输出组成,并控制输出帧的格式和分辨率。
AVCaptureDevice:封装设备上的物理摄像头。对iPhone而言有前后两个摄像头。
AVCaptureDeviceInput:要添加一个AVCaptureDevice到session中,需要用AVCaptureDeviceInput来包裹一下。
AVCaptureVideoPreviewLayer:用于显示摄像头捕捉到得视频到UI。
_running:用于存放session的状态,标明session在运行还是处于停止状态。
添加以下方法:
- (void) setupCaptureSession {
if (_captureSession) return;
_videoDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
if (!_videoDevice) {
NSLog(@"No video camera on this device!");
return;
}
_captureSession = [[AVCaptureSession alloc] init];
_videoInput = [[AVCaptureDeviceInput alloc] initWithDevice:_videoDevice error:nil];
if ([_captureSession canAddInput:_videoInput])
{
[_captureSession addInput:_videoInput];
}
_previewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:_captureSession];
_previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
}
这个方法用于建立capture session。
- 如果session已经存在,则直接返回。
- 初始化video device,若设备没有摄像头,则直接返回。
- 初始化capture session。
- 通过video device创建video input。
- 查询session是否接受一个输入,如果接受,添加输入到session中。
- 最后,创建预览层并为其指定要预览的capture session。
创建预览view
打开storyboard,添加一个UIView到view controller中,让其填充满整个view。并为其添加名为previewView的outlet。
回到ViewController.m,修改viewDidLoad方法,创建capture session,设置preview layer,让其填充满包含它的view,并将其设置为其容器view的子layer。
- (void)viewDidLoad {
[super viewDidLoad];
[self setupCaptureSession];
_previewLayer.frame = _previewView.bounds;
[_previewView.layer addSublayer:_previewLayer];
}
添加以下两个方法,用于启动和停止捕捉:
- (void) startRunning
{
if (_running)
{
return;
}
[_captureSession startRunning];
_running = YES;
}
- (void) stopRunning
{
if (!_running)
{
return;
}
[_captureSession stopRunning];
_running = NO;
}
添加另外两个方法,用于在view被显示前启动capture,在app进入后台时,停止capture:
- (void) viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[self startRunning];
}
- (void) viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
[self stopRunning];
}
修改viewDidLoad方法,注册以下两个通知:
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationWillEnterForeground:) name:UIApplicationWillEnterForegroundNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationDidEnterBackground:) name:UIApplicationDidEnterBackgroundNotification object:nil];
实现通知处理方法:
- (void)applicationWillEnterForeground:(NSNotification *)note
{
[self startRunning];
}
- (void)applicationDidEnterBackground:(NSNotification *)note
{
[self stopRunning];
}
编译,在真机上执行(模拟器不支持摄像头)效果如下:
下一节,我们将为程序添加扫码功能。
转载请注明出处:http://blog.csdn.net/yamingwu/article/details/44498123