iOS开发自定义相机(拍照,录制视频)

使用AVFoundation框架,

这里是Demo

首先声明以下对象:

#import "CustomeCameraViewController.h"
#import <AVFoundation/AVFoundation.h>
#import <AssetsLibrary/AssetsLibrary.h>

@interface CustomeCameraViewController ()<AVCaptureFileOutputRecordingDelegate>

{
    // AVCaptureSession对象来执行输入设备和输出设备之间的数据传递
    AVCaptureSession *iSession;
    //当前设备
    AVCaptureDevice *iDevice;
    //输入设备
    AVCaptureDeviceInput *iDeviceInput;
    //照片输出流
    AVCaptureStillImageOutput *iStillImageOutput;
    //预览图层
    AVCaptureVideoPreviewLayer *iPreviewLayer;
    
}
初始化各对象:

- (void)viewDidLoad {
    [super viewDidLoad];
   
    //点击屏幕对焦
    UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(focusTap:)];
    [self.view addGestureRecognizer:tap];
    
    
    iSession = [[AVCaptureSession alloc]init];
    
    NSArray *deviceArray = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];
    for (AVCaptureDevice *device in deviceArray) {
        
        //AVCaptureDevicePositionBack 后置摄像头
        //AVCaptureDevicePositionFront 前置摄像头
        if (device.position == AVCaptureDevicePositionBack) {
            iDevice = device;
        }
    }
    
    
    iSession.sessionPreset = [self getSessionPresetForDevice:iDevice];
    
    iDeviceInput = [[AVCaptureDeviceInput alloc]initWithDevice:iDevice error:nil];
    
    
    输出设置。AVVideoCodecJPEG   输出jpeg格式图片
    iStillImageOutput = [[AVCaptureStillImageOutput alloc]init];
    NSDictionary *outputDic = [NSDictionary dictionaryWithObjectsAndKeys:AVVideoCodecJPEG,AVVideoCodecKey, nil];
    [iStillImageOutput setOutputSettings:outputDic];
   
    
    //更改这个设备设置的时候必须先锁定设备,修改完后再解锁,否则崩溃
    [iDevice lockForConfiguration:nil];
    if ([iDevice isFlashModeSupported:AVCaptureFlashModeOff]) {
        [iDevice setFlashMode:AVCaptureFlashModeOff];
    }
    if ([iDevice isFocusModeSupported:AVCaptureFocusModeAutoFocus]) {
        [iDevice setFocusMode:AVCaptureFocusModeAutoFocus];
    }
    if ([iDevice isWhiteBalanceModeSupported:AVCaptureWhiteBalanceModeAutoWhiteBalance]) {
        [iDevice setWhiteBalanceMode:AVCaptureWhiteBalanceModeAutoWhiteBalance];
    }
    [iDevice unlockForConfiguration];
    
    if ([iSession canAddInput:iDeviceInput]) {
        [iSession addInput:iDeviceInput];
    }
    if ([iSession canAddOutput:iStillImageOutput]) {
        [iSession addOutput:iStillImageOutput];
    }
    if ([iSession canAddOutput:iVideoOutput]) {
        [iSession addOutput:iVideoOutput];
    }
    
    //初始化预览图层
    iPreviewLayer = [[AVCaptureVideoPreviewLayer alloc]initWithSession:iSession];
    [iPreviewLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill];
    iPreviewLayer.frame = CGRectMake(0, 60, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height-160);
    [self.iCameraView.layer addSublayer:iPreviewLayer];
    
    [iSession startRunning];
   
    
}


点击按钮拍照:

//拍照
-(void)takePictures{
    AVCaptureConnection  *connection = [iStillImageOutput connectionWithMediaType:AVMediaTypeVideo];
    if (!connection) {
        NSLog(@"失败");
        return;
    }
    //设置焦距
    [connection setVideoScaleAndCropFactor:1];
    
    [iStillImageOutput captureStillImageAsynchronouslyFromConnection:connection completionHandler:^(CMSampleBufferRef imageDataSampleBuffer, NSError *error) {
        if (imageDataSampleBuffer==NULL) {
            NSLog(@"NUll");
            return ;
        }
        
        NSData *data = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageDataSampleBuffer];
        UIImage *image = [UIImage imageWithData:data];
        
        
    }];
}
image即为拍照所得图片.


设置session的AVCaptureSessionPreset属性

-(NSString *)getSessionPresetForDevice:(AVCaptureDevice *)device{
    if ([device supportsAVCaptureSessionPreset:AVCaptureSessionPreset3840x2160]) {
        return AVCaptureSessionPreset3840x2160;
    } else if([device supportsAVCaptureSessionPreset:AVCaptureSessionPreset1920x1080]){
        return AVCaptureSessionPreset1920x1080;
    } else if ([device supportsAVCaptureSessionPreset:AVCaptureSessionPreset1280x720]){
        return AVCaptureSessionPreset1280x720;
    } else if ([device supportsAVCaptureSessionPreset:AVCaptureSessionPreset640x480]){
        return AVCaptureSessionPreset640x480;
    } else if ([device supportsAVCaptureSessionPreset:AVCaptureSessionPreset352x288]){
        return AVCaptureSessionPreset352x288;
    } else if ([device supportsAVCaptureSessionPreset:AVCaptureSessionPresetHigh]){
        return AVCaptureSessionPresetHigh;
    } else if ([device supportsAVCaptureSessionPreset:AVCaptureSessionPresetMedium]){
        return AVCaptureSessionPresetMedium;
    } else{
        return AVCaptureSessionPresetLow;
    }
}


设置闪光灯:

- (IBAction)iFlashBtn:(id)sender {
    
    [iDevice lockForConfiguration:nil];
    if (iDevice.flashMode == AVCaptureFlashModeOff) {
        if ([iDevice isFlashModeSupported:AVCaptureFlashModeOn]) {
            [iDevice setFlashMode:AVCaptureFlashModeOn];
            
            [self.iFlashBtn setBackgroundImage:[UIImage imageNamed:@"flashBtn"] forState:UIControlStateNormal];
        }
    } else if (iDevice.flashMode == AVCaptureFlashModeOn){
        if ([iDevice isFlashModeSupported:AVCaptureFlashModeOff]) {
            [iDevice setFlashMode:AVCaptureFlashModeOff];
            
             [self.iFlashBtn setBackgroundImage:[UIImage imageNamed:@"flashOffBtn"] forState:UIControlStateNormal];
        }
    }
    [iDevice unlockForConfiguration];
    
}

切换前置摄像头与后置摄像头:

- (IBAction)iChangeBtn:(id)sender {
    
   
    NSArray *array = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];
    AVCaptureDevice *newDevice = nil;
    AVCaptureDeviceInput *newDeviceInput = nil;
    
    CATransition *animation = [CATransition animation];
    animation.duration = 0.5f;
    animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    animation.type = @"oglFlip";
    
    if (iDevice.position == AVCaptureDevicePositionBack) {
        animation.subtype = kCATransitionFromLeft;
        for (AVCaptureDevice *device in array) {
            if (device.position == AVCaptureDevicePositionFront) {
                newDevice = device;
            }
        }
    } else if (iDevice.position == AVCaptureDevicePositionFront){
        animation.subtype = kCATransitionFromRight;
        for (AVCaptureDevice *device in array) {
            if (device.position == AVCaptureDevicePositionBack) {
                newDevice = device;
            }
        }
    }
    
    newDeviceInput = [AVCaptureDeviceInput deviceInputWithDevice:newDevice error:nil];
    [iPreviewLayer addAnimation:animation forKey:nil];
    if (newDeviceInput!=nil) {
        [iSession beginConfiguration];
        [iSession removeInput:iDeviceInput];
         iSession.sessionPreset = [self getSessionPresetForDevice:newDevice];
        if ([iSession canAddInput:newDeviceInput]) {
            [iSession addInput:newDeviceInput];
            iDeviceInput = newDeviceInput;
            iDevice = newDevice;
        } else {
            [iSession addInput:iDeviceInput];
        }
        [iSession commitConfiguration];
    }
    
    
}


点击屏幕对焦:

//点击屏幕对焦
-(void)focusTap:(UIGestureRecognizer *)tap{
    CGPoint tapPoint = [tap locationInView:self.view];
    
    
    float Y = tapPoint.y;
    if (Y<60 || Y>([UIScreen mainScreen].bounds.size.height-100)) {
        return;
    }
    
    [iDevice lockForConfiguration:nil];
    if ([iDevice isFocusModeSupported:AVCaptureFocusModeAutoFocus]) {
        [iDevice setFocusPointOfInterest:CGPointMake(tapPoint.x/self.view.frame.origin.x, tapPoint.y/self.view.frame.origin.y)];
        [iDevice setFocusMode:AVCaptureFocusModeAutoFocus];
    }
    [iDevice unlockForConfiguration];
    
    self.iFocusImgView.center = tapPoint;
    self.iFocusImgView.hidden = NO;
    [UIView animateWithDuration:0.3 animations:^{
        self.iFocusImgView.transform = CGAffineTransformMakeScale(1.25, 1.25);
    }completion:^(BOOL finished) {
        [UIView animateWithDuration:0.5 animations:^{
            self.iFocusImgView.transform = CGAffineTransformIdentity;
        } completion:^(BOOL finished) {
            self.iFocusImgView.hidden = YES;
        }];
    }];
}


关于视频录制可以在Demo中查看。




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值