美文网首页
iOS 拍照

iOS 拍照

作者: 索性流年 | 来源:发表于2019-01-07 15:43 被阅读0次

    使用系统框架AVFoundation下的:

    <AVCapturePhotoCaptureDelegate>进行拍照

    创建LyPhotoCollection继承与UIView

    .h

    #import <AVFoundation/AVFoundation.h>
    #import <Photos/Photos.h>
    //回调
    @property(nonatomic,copy)void (^photoComesBlack) (UIImage *photoImage);
    //拍照
    -(void)shutterCamera;
    // 闪光灯开关
    -(void)lightAction;
    //停止运行
    -(void)stopRunning;
    //开始运行
    -(void)startRunning;
    /**
     切换前后摄像头
     @param camera 前置、后置
     */
    - (void)cameraPosition:(NSString *)camera;
    //照片保存到相册
    - (void)saveImageWithImage:(UIImage *)image;
    //放大缩小屏幕
    - (void)viewScaleChnageValue:(CGFloat )sender;
    

    .m

    @interface LyPhotoCollection () <AVCapturePhotoCaptureDelegate>
     @property (nonatomic, strong) AVCaptureSession *captureSession; // 会话
    @property (nonatomic, strong) AVCaptureDevice * captureDevice;   // 输入设备
    @property (nonatomic, strong) AVCaptureDeviceInput * captureDeviceInput; // 输入源
    @property (nonatomic, strong) AVCapturePhotoOutput *photoOutput;    // 图像输出
    @property (nonatomic, strong) AVCaptureVideoPreviewLayer *previewLayer; // 预览画面
    @property (nonatomic, strong) AVCapturePhotoSettings *photoSettings;    // 图像设置
    @property (nonatomic, assign) AVCaptureFlashMode mode;
    @property (nonatomic, assign) AVCaptureDevicePosition position;
    @end
    
    - (instancetype)initWithFrame:(CGRect)frame
    {
        self = [super initWithFrame:frame];
        if (self) {
            [self.layer insertSublayer:self.previewLayer atIndex:0];
            // 5. 连接输入与会话
            if ([self.captureSession canAddInput:self.captureDeviceInput]) {
                [self.captureSession addInput:self.captureDeviceInput];
            }
            // 6. 连接输出与会话
            if ([self.captureSession canAddOutput:self.photoOutput]) {
                [self.captureSession addOutput:self.photoOutput];
            }
            [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationDidBecomeActive) name:UIApplicationWillEnterForegroundNotification object:nil];
        
        }
        return self;
    }
    
    
    #pragma mark - 监听是否重新进入程序程序
    -(void)applicationDidBecomeActive{
        if (self.captureSession.isRunning != YES) {
            dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
                [self.captureSession startRunning];
            });
        }
    }
    
    -(void)layoutSubviews{
        [super layoutSubviews];
        self.previewLayer.frame = self.bounds;
        //    [self.previewLayer removeFromSuperlayer];
        [self startRunning];
    }
    
    
    #pragma mark - 开始运行
    -(void)startRunning{
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
            [self.captureSession startRunning];
        });
    }
    
    
    #pragma mark - 停止运行
    -(void)stopRunning{
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
            [self.captureSession stopRunning];
        });
    }
    
    #pragma mark - 调整焦距
    - (void)cameraBackgroundDidChangeFocus:(CGFloat)focus{
        AVCaptureDevice *captureDevice = [self.captureDeviceInput device];
        NSError *error;
        if ([captureDevice lockForConfiguration:&error]) {
            if ([captureDevice isFocusModeSupported:AVCaptureFocusModeContinuousAutoFocus]){
                [captureDevice setFocusModeLockedWithLensPosition:focus completionHandler:nil];
            }
        }
        else{
            // Handle the error appropriately.
        }
    }
    
    
    #pragma mark - 放大缩小屏幕
    - (void)viewScaleChnageValue:(CGFloat )sender
    {
        self.transform = CGAffineTransformMakeScale(sender, sender);
    }
    
    
    #pragma mark - 拍照
    -(void)shutterCamera{
        self.photoSettings = [AVCapturePhotoSettings photoSettingsWithFormat:@{AVVideoCodecKey:AVVideoCodecJPEG}];
        [self.photoSettings setFlashMode:self.mode];
        if (!self.previewLayer || !self.photoOutput || !self.photoSettings) {
            return;
        }
        if (self.captureSession.isRunning == YES) {
            [self.photoOutput capturePhotoWithSettings:self.photoSettings delegate:self];
        }
    }
    
    #pragma mark - 闪光灯开关
    -(void)lightAction{
        if (self.mode == AVCaptureFlashModeOn) {
            [self setMode:AVCaptureFlashModeOff];
        } else {
                [self setMode:AVCaptureFlashModeOn];
            }
        }
    
    
    #pragma mark - 切换前后摄像头
    - (void)cameraPosition:(NSString *)camera{
        if ([camera isEqualToString:@"前置"]) {
            if (self.captureDevice.position != AVCaptureDevicePositionFront) {
                self.position = AVCaptureDevicePositionFront;
            }
        }
        else if ([camera isEqualToString:@"后置"]){
            if (self.captureDevice.position != AVCaptureDevicePositionBack) {
                self.position = AVCaptureDevicePositionBack;
            }
        }
    
        AVCaptureDevice * device = [AVCaptureDevice defaultDeviceWithDeviceType:AVCaptureDeviceTypeBuiltInWideAngleCamera mediaType:AVMediaTypeVideo position:self.position];
        if (device) {
            self.captureDevice = device;
            AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:self.captureDevice error:nil];
            [self.captureSession beginConfiguration];
            [self.captureSession removeInput:self.captureDeviceInput];
            if ([self.captureSession canAddInput:input]) {
                [self.captureSession addInput:input];
                self.captureDeviceInput = input;
                [self.captureSession commitConfiguration];
            }
        }
    }
    
    
    #pragma mark - 拍照回调代理
    - (void)captureOutput:(AVCapturePhotoOutput *)output didFinishProcessingPhoto:(AVCapturePhoto *)photo error:(NSError *)error{
    if (!error) {
        NSData *imageData = [photo fileDataRepresentation];
        UIImage *image = [self transfor:[UIImage imageWithData:imageData]];
        [self saveImageWithImage:image];
        if (image) {
            if (self.photoBlack) {
                self.photoBlack(image);
            }
            [self saveImageWithImage:image];
        }
    }
    }
    
    
    #pragma mark - 解决图片绘制自动旋转90度的问题
    -(UIImage *)transfor:(UIImage *)image{
        int destWidth = image.size.width;
        int destHeight = image.size.height;
        UIGraphicsBeginImageContext(CGSizeMake(destWidth, destHeight));
        [image drawInRect:CGRectMake(0,0,destWidth,  destHeight)];
        UIImage * newImage = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
        return newImage;
    }
    
    #pragma mark - 保存图片到相册
    - (void)saveImageWithImage:(UIImage *)image{
        //    // 判断授权状态
        [PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {
            if (status != PHAuthorizationStatusAuthorized) return;
            dispatch_async(dispatch_get_main_queue(), ^{
                NSError *error = nil;
                // 保存相片到相机胶卷
                __block PHObjectPlaceholder *createdAsset = nil;
                [[PHPhotoLibrary sharedPhotoLibrary] performChangesAndWait:^{
                    createdAsset = [PHAssetCreationRequest creationRequestForAssetFromImage:image].placeholderForCreatedAsset;
                } error:&error];
            
                if (error) {
                    NSLog(@"保存失败:%@", error);
                    return;
                }
            });
        }];
    }
    
    -(AVCaptureDevicePosition)position{
        if (!_position) {
            _position = AVCaptureDevicePositionFront;
        }
        return _position;
    }
    
    
    #pragma mark - 创建会话
    -(AVCaptureSession *)captureSession{
    if (!_captureSession) {
        _captureSession = [[AVCaptureSession alloc] init];
        _captureSession.sessionPreset = AVCaptureSessionPresetPhoto; // 画质
    }
    return _captureSession;
    }
    
    
    #pragma mark - 创建输入设备
    -(AVCaptureDevice *)captureDevice{
        if (!_captureDevice) {
        //        设置默认前置摄像头
        _captureDevice = [AVCaptureDevice defaultDeviceWithDeviceType:AVCaptureDeviceTypeBuiltInWideAngleCamera mediaType:AVMediaTypeVideo position:AVCaptureDevicePositionFront];
        }
        return _captureDevice;
    }
    
    #pragma mark - 创建输入源
    -(AVCaptureDeviceInput *)captureDeviceInput{
        if (!_captureDeviceInput) {
            _captureDeviceInput = [AVCaptureDeviceInput deviceInputWithDevice:self.captureDevice error:nil];
        }
        return _captureDeviceInput;
    }
    
    #pragma mark - 创建图像输出
    -(AVCapturePhotoOutput *)photoOutput{
        if (!_photoOutput) {
            _photoOutput = [[AVCapturePhotoOutput alloc] init];
        }
        return _photoOutput;
    }
    
    
    -(AVCaptureVideoPreviewLayer *)previewLayer{
        if (!_previewLayer) {
            _previewLayer = [AVCaptureVideoPreviewLayer layerWithSession:self.captureSession];
            _previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
        }
        return _previewLayer;
    }
    
    -(void)dealloc{
        [[NSNotificationCenter defaultCenter] removeObserver:self];
    }
    

    调用拍照方法

    //引入头文件
    #import "LyPhotoCollection.h"
    
    //拍照视图
    @property(nonatomic,strong)LyPhotoCollection * lyPhotoV;
    
    //加入视图
    [self.view addSubview:self.lyPhotoV];
    
    #pragma mark - 拍照视图
    -(LyPhotoCollection *)lyPhotoV{
        if (!_lyPhotoV) {
            _lyPhotoV = [[LyPhotoCollection alloc]init];
        }
        return _lyPhotoV;
    }
    
    -(void)viewDidLayoutSubviews{
        [super viewDidLayoutSubviews];
        _lyPhotoV.frame = self.view.bounds;
    }
    //在需要的地方调用拍照
    [_lyPhotoV shutterCamera];

    相关文章

      网友评论

          本文标题:iOS 拍照

          本文链接:https://www.haomeiwen.com/subject/tzmurqtx.html