涉及到的类
AVCaptureSession会话层AVCaptureDevice 创建 配置输入设备AVCaptureDeviceInput 输入AVCaptureStillImageOutput 输出AVCaptureVideoPreviewLayer layer层UIImageOrientation 图片朝向需要遵循的协议
AVCaptureVideoDataOutputSampleBufferDelegate
初始化
//1.创建会话层
self.session = [[[AVCaptureSession alloc] init] autorelease];
[self.session setSessionPreset:AVCaptureSessionPresetPhoto];
//2.创建、配置输入设备
AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
#if 1
int flags = NSKeyValueObservingOptionNew; //监听自动对焦
[device addObserver:self forKeyPath:@"adjustingFocus" options:flags context:nil];
#endif
NSError *error;
AVCaptureDeviceInput *captureInput = [AVCaptureDeviceInput deviceInputWithDevice:device error:&error];
if (!captureInput)
{
NSLog(@"Error: %@", error);
return;
}
[self.session addInput:captureInput];
//3.创建、配置输出
captureOutput = [[[AVCaptureStillImageOutput alloc] init] autorelease];
NSDictionary *outputSettings = [[NSDictionary alloc] initWithObjectsAndKeys:AVVideoCodecJPEG,AVVideoCodecKey,nil];
[captureOutput setOutputSettings:outputSettings];
[outputSettings release];
[self.session addOutput:captureOutput];
KVO回调
//对焦回调
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
if( [keyPath isEqualToString:@"adjustingFocus"] ){
BOOL adjustingFocus = [ [change objectForKey:NSKeyValueChangeNewKey] isEqualToNumber:[NSNumber numberWithInt:1] ];
NSLog(@"Is adjusting focus? %@", adjustingFocus ? @"YES" : @"NO" );
NSLog(@"Change dictionary: %@", change);
if (delegate) {
[delegate foucusStatus:adjustingFocus];
}
}
}
嵌入摄像头捕捉的界面
-(void) embedPreviewInView: (UIView *) aView {
if (!session) return;
//设置取景
preview = [AVCaptureVideoPreviewLayer layerWithSession: session];
preview.frame = aView.bounds;
preview.videoGravity = AVLayerVideoGravityResizeAspectFill;
[aView.layer addSublayer: preview];
}
横竖屏适配
- (void)changePreviewOrientation:(UIInterfaceOrientation)interfaceOrientation
{
if (!preview) {
return;
}
[CATransaction begin];
if (interfaceOrientation == UIInterfaceOrientationLandscapeRight) {
g_orientation = UIImageOrientationUp;
preview.connection.videoOrientation = AVCaptureVideoOrientationLandscapeRight;
}else if (interfaceOrientation == UIInterfaceOrientationLandscapeLeft){
g_orientation = UIImageOrientationDown;
preview.connection.videoOrientation = AVCaptureVideoOrientationLandscapeLeft;
}else if (interfaceOrientation == UIDeviceOrientationPortrait){
g_orientation = UIImageOrientationRight;
preview.connection.videoOrientation = AVCaptureVideoOrientationPortrait;
}else if (interfaceOrientation == UIDeviceOrientationPortraitUpsideDown){
g_orientation = UIImageOrientationLeft;
preview.connection.videoOrientation = AVCaptureVideoOrientationPortraitUpsideDown;
}
[CATransaction commit];
}
### 开始工作/停止工作/拍照
- (void) startRunning
{
[[self session] startRunning];
}
- (void) stopRunning
{
[[self session] stopRunning];
}
-(void)CaptureStillImage
{
[self Captureimage];
}
拍照
-(void)Captureimage
{
//get connection
AVCaptureConnection *videoConnection = nil;
for (AVCaptureConnection *connection in captureOutput.connections) {
for (AVCaptureInputPort *port in [connection inputPorts]) {
if ([[port mediaType] isEqual:AVMediaTypeVideo] ) {
videoConnection = connection;
break;
}
}
if (videoConnection) { break; }
}
//get UIImage
[captureOutput captureStillImageAsynchronouslyFromConnection:videoConnection completionHandler:
^(CMSampleBufferRef imageSampleBuffer, NSError *error) {
CFDictionaryRef exifAttachments =
CMGetAttachment(imageSampleBuffer, kCGImagePropertyExifDictionary, NULL);
if (exifAttachments) {
// Do something with the attachments.
}
// Continue as appropriate.
NSData *imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageSampleBuffer];
UIImage *t_image = [UIImage imageWithData:imageData];
image = [[UIImage alloc]initWithCGImage:t_image.CGImage scale:1.0 orientation:g_orientation];
[self giveImg2Delegate];
}];
}
#pragma mark 切换前后摄像头
- (IBAction)toggleButtonClick:(UIButton *)sender {
AVCaptureDevice *currentDevice=[self.captureDeviceInput device];
AVCaptureDevicePosition currentPosition=[currentDevice position];
[self removeNotificationFromCaptureDevice:currentDevice];
AVCaptureDevice *toChangeDevice;
AVCaptureDevicePosition toChangePosition=AVCaptureDevicePositionFront;
if (currentPosition==AVCaptureDevicePositionUnspecified||currentPosition==AVCaptureDevicePositionFront) {
toChangePosition=AVCaptureDevicePositionBack;
}
toChangeDevice=[self getCameraDeviceWithPosition:toChangePosition];
[self addNotificationToCaptureDevice:toChangeDevice];
//获得要调整的设备输入对象
AVCaptureDeviceInput *toChangeDeviceInput=[[AVCaptureDeviceInput alloc]initWithDevice:toChangeDevice error:nil];
//改变会话的配置前一定要先开启配置,配置完成后提交配置改变
[self.captureSession beginConfiguration];
//移除原有输入对象
[self.captureSession removeInput:self.captureDeviceInput];
//添加新的输入对象
if ([self.captureSession canAddInput:toChangeDeviceInput]) {
[self.captureSession addInput:toChangeDeviceInput];
self.captureDeviceInput=toChangeDeviceInput;
}
//提交会话配置
[self.captureSession commitConfiguration];
[self setFlashModeButtonStatus];
}
#pragma mark 自动闪光灯开启
- (IBAction)flashAutoClick:(UIButton *)sender {
[self setFlashMode:AVCaptureFlashModeAuto];
[self setFlashModeButtonStatus];
}
#pragma mark 打开闪光灯
- (IBAction)flashOnClick:(UIButton *)sender {
[self setFlashMode:AVCaptureFlashModeOn];
[self setFlashModeButtonStatus];
}
#pragma mark 关闭闪光灯
- (IBAction)flashOffClick:(UIButton *)sender {
[self setFlashMode:AVCaptureFlashModeOff];
[self setFlashModeButtonStatus];
}
/**
* 设置聚焦点
*
* @param point 聚焦点
*/
-(void)focusWithMode:(AVCaptureFocusMode)focusMode exposureMode:(AVCaptureExposureMode)exposureMode atPoint:(CGPoint)point{
[self changeDeviceProperty:^(AVCaptureDevice *captureDevice) {
if ([captureDevice isFocusModeSupported:focusMode]) {
[captureDevice setFocusMode:AVCaptureFocusModeAutoFocus];
}
if ([captureDevice isFocusPointOfInterestSupported]) {
[captureDevice setFocusPointOfInterest:point];
}
if ([captureDevice isExposureModeSupported:exposureMode]) {
[captureDevice setExposureMode:AVCaptureExposureModeAutoExpose];
}
if ([captureDevice isExposurePointOfInterestSupported]) {
[captureDevice setExposurePointOfInterest:point];
}
}];
}
/**
* 添加点按手势,点按时聚焦
*/
-(void)addGenstureRecognizer{
UITapGestureRecognizer *tapGesture=[[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(tapScreen:)];
[self.viewContainer addGestureRecognizer:tapGesture];
}
-(void)tapScreen:(UITapGestureRecognizer *)tapGesture{
CGPoint point= [tapGesture locationInView:self.viewContainer];
//将UI坐标转化为摄像头坐标
CGPoint cameraPoint= [self.captureVideoPreviewLayer captureDevicePointOfInterestForPoint:point];
[self setFocusCursorWithPoint:point];
[self focusWithMode:AVCaptureFocusModeAutoFocus exposureMode:AVCaptureExposureModeAutoExpose atPoint:cameraPoint];
}
###本文代码
请查看此目录下面的 wx2 文件夹