ios 自定义相机

.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];
        }
    }];
}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容