.h文件
@protocol UICameraViewControllerDelegate <NSObject>
/**
照相完成
@param cameravc 照相控制器
@param info 携带信息:result:1代表成功,UIImagePickerControllerOriginalImage中含图片
*/
- (void)imageCameraController:(CameraViewController *)cameravc
didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info;
/**
用户取消拍照
@param cameravc 照相控制器
*/
- (void)imageCameraControllerDidCancel:(CameraViewController *)cameravc;
@end
@interface CameraViewController : UIViewController
/**
相机代理
*/
@property (nonatomic, assign) id <UICameraViewControllerDelegate> delegate;
.m文件
//捕获设备
@property(nonatomic, strong) AVCaptureDevice *device;
//AVCaptureDeviceInput 代表输入设备,他使用AVCaptureDevice 来初始化
@property(nonatomic, strong) AVCaptureDeviceInput *input;
//当启动摄像头开始捕获输入
@property(nonatomic, strong) AVCaptureMetadataOutput *output;
//session:由他把输入输出结合在一起,并开始启动捕获设备(摄像头)
@property(nonatomic, strong) AVCaptureSession *session;
//输出
@property (nonatomic, strong) AVCaptureStillImageOutput *ImageOutPut;
//图像预览层,实时显示捕获的图像
@property(nonatomic, strong) AVCaptureVideoPreviewLayer *previewLayer;
//聚焦
@property (nonatomic, strong) UIView *focusView;
//截取的图片
@property (nonatomic, strong) UIImage *image;
//截取的图片显示view
@property (nonatomic, strong) UIImageView *imageView;
/**
取消按钮
*/
@property (nonatomic, strong) UIButton *cancelButton;
//使用AVMediaTypeVideo 指明self.device代表视频,默认使用后置摄像头进行初始化
self.device = [self cameraWithPosition:AVCaptureDevicePositionFront];
//使用设备初始化输入
self.input = [[AVCaptureDeviceInput alloc]initWithDevice:self.device error:nil];
//生成输出对象
self.output = [[AVCaptureMetadataOutput alloc] init];
self.ImageOutPut = [[AVCaptureStillImageOutput alloc] init];
//生成会话,用来结合输入输出
self.session = [[AVCaptureSession alloc] init];
if ([self.session canSetSessionPreset:AVCaptureSessionPresetiFrame1280x720]) {
self.session.sessionPreset = AVCaptureSessionPresetHigh;
}
if ([self.session canAddInput:self.input]) {
[self.session addInput:self.input];
}
if ([self.session canAddOutput:self.ImageOutPut]) {
[self.session addOutput:self.ImageOutPut];
}
//使用self.session,初始化预览层,self.session负责驱动input进行信息的采集,layer负责把图像渲染显示
self.previewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:self.session];
self.previewLayer.frame = CGRectMake(0, 0, ScreenWidth, ScreenHeight);
self.previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
[self.view.layer addSublayer:self.previewLayer];
//开始启动
[self.session startRunning];
//关闪光灯
if ([_device lockForConfiguration:nil]) {
if (_device.flashMode != AVCaptureFlashModeOff) {
[_device setFlashMode:AVCaptureFlashModeOff];
}
//自动白平衡
if ([_device isWhiteBalanceModeSupported:AVCaptureWhiteBalanceModeAutoWhiteBalance]) {
[_device setWhiteBalanceMode:AVCaptureWhiteBalanceModeAutoWhiteBalance];
}
[_device unlockForConfiguration];
}
/**
获取前置/后置摄像头
@param position 前置/后置
@return 获取前置/后置摄像头device
*/
- (AVCaptureDevice *)cameraWithPosition:(AVCaptureDevicePosition)position {
NSArray *devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];
for ( AVCaptureDevice *device in devices )
if ( device.position == position ) return device;
return nil;
}
/**
截取照片
*/
- (void)takePhoto {
AVCaptureConnection * videoConnection = [self.ImageOutPut connectionWithMediaType:AVMediaTypeVideo];
if (!videoConnection) {
NSLog(@"take photo failed!");
[self takePhotoFailed];
return;
}
//去掉系统声音
if (soundID == 0 && self.delegate != nil) {
NSString *path = [[NSBundle mainBundle] pathForResource:@"photoShutter2" ofType:@"caf"];
NSURL *filePath = [NSURL fileURLWithPath:path];
AudioServicesCreateSystemSoundID((__bridge CFURLRef)filePath, &soundID);
}
AudioServicesPlaySystemSound(soundID);
[self.ImageOutPut captureStillImageAsynchronouslyFromConnection:videoConnection completionHandler:^(CMSampleBufferRef imageDataSampleBuffer, NSError *error) {
if (imageDataSampleBuffer == NULL) {
[self takePhotoFailed];
return;
}
NSData *imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageDataSampleBuffer];
self.image = [UIImage imageWithData:imageData];
self.imageView.layer.masksToBounds = YES;
self.imageView.image = _image;
if (self.delegate && [self.delegate respondsToSelector:@selector(imageCameraController:didFinishPickingMediaWithInfo:)]) {
NSDictionary *dic = @{@"result": @"1", @"UIImagePickerControllerOriginalImage" : _image};
[self.delegate imageCameraController:self didFinishPickingMediaWithInfo:dic];
}
}];
}