需求:要求在APP界面内实现拍照功能,分析通常我们都会调用UIImagePickerController来调用系统提供的相机来拍照,这个控件非常好用。但是有时UIImagePickerController控件无法满足我们的需求,例如我们需要更加复杂的OverlayerView、需要在APP内实现,这时候我们就要自己构造一个摄像机控件了。
0.AVCapture <AVFoundation/AVFoundation.h>
媒体采集需要的几个对象:
1、AVCaptureDevice: 代表抽象的硬件设备(如前置摄像头,后置摄像头等)。
2、AVCaptureInput: 代表输入设备(可以是它的子类),它配置抽象硬件设备的ports。
3、AVCaptureOutput: 它代表输出数据,管理着输出到一个movie或者图像。
4、AVCaptureSession: 它是input和output的桥梁。它协调着input到output的数据传输。
首先声明以下对象:
#import <AVFoundation/AVFoundation.h>
#import <AssetsLibrary/AssetsLibrary.h>
/*
* AVCaptureSession:它从物理设备得到数据流(比如摄像头和麦克风),输出到一个或
* 多个目的地,它可以通过
* 会话预设值(session preset),来控制捕捉数据的格式和质量
*/
@property (nonatomic, strong) AVCaptureSession *iSession;
//设备
@property (nonatomic, strong) AVCaptureDevice *iDevice;
//输入
@property (nonatomic, strong) AVCaptureDeviceInput *iInput;
//照片输出
@property (nonatomic, strong) AVCaptureStillImageOutput *iOutput;
//预览层
@property (nonatomic, strong) AVCaptureVideoPreviewLayer *iPreviewLayer;
实现布局:
- (void)showPhotosView{
self.iSession = [[AVCaptureSession alloc]init];
self.iSession.sessionPreset = AVCaptureSessionPresetHigh;
NSArray *deviceArray = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];
for (AVCaptureDevice *device in deviceArray) {
if (device.position == AVCaptureDevicePositionBack) {
self.iDevice = device;
}
}
//添加摄像头设备
//对设备进行设置时需上锁,设置完再打开锁
[self.iDevice lockForConfiguration:nil];
if ([self.iDevice isFlashModeSupported:AVCaptureFlashModeAuto]) {
[self.iDevice setFlashMode:AVCaptureFlashModeAuto];
}
if ([self.iDevice isFocusModeSupported:AVCaptureFocusModeAutoFocus]) {
[self.iDevice setFocusMode:AVCaptureFocusModeAutoFocus];
}
if ([self.iDevice isWhiteBalanceModeSupported:AVCaptureWhiteBalanceModeAutoWhiteBalance]) {
[self.iDevice setWhiteBalanceMode:AVCaptureWhiteBalanceModeAutoWhiteBalance];
}
[self.iDevice unlockForConfiguration];
self.iInput = [[AVCaptureDeviceInput alloc]initWithDevice:self.iDevice error:nil];
self.iOutput = [[AVCaptureStillImageOutput alloc]init];
NSDictionary *setDic = [NSDictionary dictionaryWithObjectsAndKeys:AVVideoCodecJPEG,AVVideoCodecKey, nil];
self.iOutput.outputSettings = setDic;
if ([self.iSession canAddInput:self.iInput]) {
[self.iSession addInput:self.iInput];
}
if ([self.iSession canAddOutput:self.iOutput]) {
[self.iSession addOutput:self.iOutput];
}
self.iPreviewLayer = [[AVCaptureVideoPreviewLayer alloc]initWithSession:self.iSession];
[self.iPreviewLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill];
self.iPreviewLayer.frame = [UIScreen mainScreen].bounds;
[self.photoView.layer insertSublayer:self.iPreviewLayer atIndex:0];
[self.iSession startRunning];
}
拍照方法:
- (IBAction)photoBtn:(id)sender {
AVCaptureConnection *connection = [self.iOutput connectionWithMediaType:AVMediaTypeVideo];
if (!connection) {
[[CustomeAlertView shareView] showCustomeAlertViewWithMessage:@"Default"];
} else{
[self.iOutput captureStillImageAsynchronouslyFromConnection:connection completionHandler:^(CMSampleBufferRef imageDataSampleBuffer, NSError *error) {
if (!imageDataSampleBuffer) {
[[CustomeAlertView shareView] showCustomeAlertViewWithMessage:@"Default"];
} else{
[[CustomeAlertView shareView] showCustomeAlertViewWithMessage:@"Success"];
NSData *imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageDataSampleBuffer];
UIImage *image = [UIImage imageWithData:imageData];
[self.editPhotoView addOneImage:image];
// UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil);
}
}];
}
}
-(void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
if (self.iSession) {
[self.iSession startRunning];
}
}
-(void)viewWillDisappear:(BOOL)animated{
[super viewWillDisappear:animated];
if (self.iSession) {
[self.iSession stopRunning];
}
}
参考链接https://blog.csdn.net/qq_21649645/article/details/50739609,https://blog.csdn.net/qq_38370919/article/details/73642494