从这一节开始,我们使用AV Foundation制作一个条码(不仅仅是二维码)扫描程序,除了扫描二维码功能外,还具备语音合成和摄像头缩放功能。
创建名为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