涉及到的类
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
文件夹