• 自定制相机(拍照)


    #import <AVFoundation/AVFoundation.h>  //基于这个框架

    #import <AssetsLibrary/AssetsLibrary.h>  //用于写入相册

     

    @interface ViewController ()<UIGestureRecognizerDelegate>

    {

        UIButton *_takePhotoBtn;  //拍照

        UIButton *_flashBtn; //闪光灯

        UIButton *_switchCameraBtn; //切换摄像头

        

    }

    @property(nonatomic)dispatch_queue_t sessionQueue;

     

    @property(nonatomic,strong)AVCaptureSession *session; //传递

    @property(nonatomic,strong)AVCaptureDeviceInput *videoInput;

    @property(nonatomic,strong)AVCaptureStillImageOutput *stillImageOut;

    @property(nonatomic,strong)AVCaptureVideoPreviewLayer *previewLayer;

     

    @property(nonatomic,assign)CGFloat beginGestureScale;

    @property(nonatomic,assign)CGFloat effectiveScale;

     

    @property(nonatomic,assign)BOOL isUsingFrontFacingCamera;

     

    @end

     

    @implementation ViewController

     

    - (void)viewWillAppear:(BOOL)animated{

        [super viewWillAppear:animated];

        [self.session startRunning];

    }

    - (void)viewWillDisappear:(BOOL)animated{

        [super viewWillDisappear:animated];

        

        [self.session stopRunning];

    }

     

    - (void)viewDidLoad {

        [super viewDidLoad];

        self.view.backgroundColor = [UIColor orangeColor];

        

        [self createUI];

        

        [self initAVCaptureSession];

        [self setUpGesture];

        

        _isUsingFrontFacingCamera = NO;

        

        self.effectiveScale = self.beginGestureScale = 1.0f;

        

    }

     

    - (void)createUI{

        _takePhotoBtn = [[UIButton alloc]initWithFrame:CGRectMake(20, 20, 80, 35)];

        _takePhotoBtn.backgroundColor = [UIColor redColor];

        [_takePhotoBtn setTitle:@"拍照" forState:UIControlStateNormal];

        [_takePhotoBtn addTarget:self action:@selector(takePhotoBtnClick:) forControlEvents:UIControlEventTouchUpInside];

        [self.view addSubview:_takePhotoBtn];

        

        _flashBtn = [[UIButton alloc]initWithFrame:CGRectMake(20 + 80 + 20, 20, 80, 35)];

        _flashBtn.backgroundColor = [UIColor redColor];

        [_flashBtn setTitle:@"闪光灯" forState:UIControlStateNormal];

        [_flashBtn addTarget:self action:@selector(flashBtnClick:) forControlEvents:UIControlEventTouchUpInside];

        [self.view addSubview:_flashBtn];

        

        _switchCameraBtn = [[UIButton alloc]initWithFrame:CGRectMake(20 + 200, 20, 80, 35)];

        _switchCameraBtn.backgroundColor = [UIColor redColor];

        [_switchCameraBtn setTitle:@"切换" forState:UIControlStateNormal];

        [_switchCameraBtn addTarget:self action:@selector(switchBtnClick:) forControlEvents:UIControlEventTouchUpInside];

        [self.view addSubview:_switchCameraBtn];

        

        

        

    }

     

     

     

     

     

     

    - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation{

        

        return (toInterfaceOrientation == UIInterfaceOrientationPortrait);

    //    这个是是否支持屏幕旋转的。

    //    如果return yes,那就是支持4个屏幕方向的。

    }

     

    #pragma mark -- 初始化变量

    - (void)initAVCaptureSession{

        self.session = [[AVCaptureSession alloc]init];

        NSError *error;

        //设备

        AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];

        //先锁定

        [device lockForConfiguration:nil];

        //闪光灯 自动

        [device setFlashMode: AVCaptureFlashModeAuto];

        [device unlockForConfiguration];

        

        self.videoInput = [[AVCaptureDeviceInput alloc]initWithDevice:device error:&error];

        if (error) {

            NSLog(@"%@",error);

        }

        self.stillImageOut = [[AVCaptureStillImageOutput alloc]init];

        //输出设置

        NSDictionary *outputSetting = [[NSDictionary alloc]initWithObjectsAndKeys:AVVideoCodecJPEG,AVVideoCodecKey, nil];

        [self.stillImageOut setOutputSettings:outputSetting];

        

        if ([self.session canAddInput:self.videoInput]) {

            [self.session addInput:self.videoInput];

        }

        if ([self.session canAddOutput:self.stillImageOut]) {

            [self.session addOutput:self.stillImageOut];

        }

        

        //预览层

        self.previewLayer = [[AVCaptureVideoPreviewLayer alloc]initWithSession:self.session];

        [self.previewLayer setVideoGravity:AVLayerVideoGravityResizeAspect];

        self.previewLayer.frame = CGRectMake(0, 64, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height - 2*64);

        self.view.layer.masksToBounds = YES;

        [self.view.layer addSublayer:self.previewLayer];

     

        

    }

     

     

    #pragma mark 获取方向 的方法

    - (AVCaptureVideoOrientation)avOrientationForDeviceOrientation:(UIDeviceOrientation) deviceOrientation{

        AVCaptureVideoOrientation result = (AVCaptureVideoOrientation)deviceOrientation;

        if (deviceOrientation == UIDeviceOrientationLandscapeLeft) {

            result = AVCaptureVideoOrientationLandscapeRight;

        }else if (deviceOrientation == UIDeviceOrientationLandscapeRight){

            result = AVCaptureVideoOrientationLandscapeLeft;

        }

        

        return result;

    }

     

     

     

     

     

     

    #pragma mark --手势

    - (void)setUpGesture{

        UIPinchGestureRecognizer *pinch = [[UIPinchGestureRecognizer alloc]initWithTarget:self action:@selector(handlePinchGesture:)];

        pinch.delegate = self;

        [self.view addGestureRecognizer:pinch];

    }

    - (void)handlePinchGesture:(UIPinchGestureRecognizer *)recoginzer{

        NSLog(@"缩放");

        

        

    }

     

    #pragma mark - 手势delegate

    - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer{

        

        if ([gestureRecognizer isKindOfClass:[UIPinchGestureRecognizer class]]) {

            self.beginGestureScale = self.effectiveScale;

        }

        

        return YES;

    }

     

    #pragma mark   btnClicke

    #pragma mark  拍照

    - (void)takePhotoBtnClick:(UIButton *)btn{

        NSLog( @"拍照");

        AVCaptureConnection *stillImageConnection = [self.stillImageOut connectionWithMediaType:AVMediaTypeVideo];

        UIDeviceOrientation curDeviceOrientation = [[UIDevice currentDevice] orientation];

        AVCaptureVideoOrientation avcaptureOrientation = [self avOrientationForDeviceOrientation:curDeviceOrientation];

        [stillImageConnection setVideoOrientation: avcaptureOrientation];

        [stillImageConnection setVideoScaleAndCropFactor:self.effectiveScale];

        

        

    ////写入相册

        [self.stillImageOut captureStillImageAsynchronouslyFromConnection:stillImageConnection completionHandler:^(CMSampleBufferRef imageDataSampleBuffer, NSError *error) {

            

            NSData *jpegData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageDataSampleBuffer];

            

    //        UIImage *image = [UIImage imageWithData:jpegData];

    //        UIImageWriteToSavedPhotosAlbum(image, self, nil, nil);  //此方法写入相册 太慢

     

            

            CFDictionaryRef attachments = CMCopyDictionaryOfAttachments(kCFAllocatorDefault, imageDataSampleBuffer, kCMAttachmentMode_ShouldPropagate);

            ALAuthorizationStatus author = [ALAssetsLibrary authorizationStatus];

            if (author == ALAuthorizationStatusRestricted || author == ALAuthorizationStatusDenied) {

                

                return ;

            }

            ALAssetsLibrary *library = [[ALAssetsLibrary alloc]init];

            [library writeImageDataToSavedPhotosAlbum:jpegData metadata:(__bridge id)attachments completionBlock:^(NSURL *assetURL, NSError *error) {

                

            }];

            

            

        }];

        

        

    //

     

        

        

    }

     

    #pragma mark 闪光灯

    - (void)flashBtnClick:(UIButton *)btn{

        NSLog(@"闪光灯");

        AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];

        [device lockForConfiguration:nil];

        //必须先判断是否有闪光灯,否则崩溃

        if ([device hasFlash]) {

            if (device.flashMode ==  AVCaptureFlashModeOff) {

                device.flashMode = AVCaptureFlashModeOn;

                [btn setTitle:@"On" forState:UIControlStateNormal];

            }else if (device.flashMode == AVCaptureFlashModeOn){

                device.flashMode = AVCaptureFlashModeAuto;

                [btn setTitle:@"Auto" forState:UIControlStateNormal];

            }else if (device.flashMode == AVCaptureFlashModeAuto){

                device.flashMode = AVCaptureFlashModeOff;

                [btn setTitle:@"Off" forState:UIControlStateNormal];

            }

            

            

            

        }else{

            

            UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"提示" message:@"设备不支持闪光灯" preferredStyle:UIAlertControllerStyleAlert];

            

            [self presentViewController:alert animated:YES completion:nil];

        }

        

        

        [device unlockForConfiguration];

        

    }

     

    #pragma mark  切换摄像头

    - (void)switchBtnClick:(UIButton *)btn{

     

        AVCaptureDevicePosition devicePositon;

        if (_isUsingFrontFacingCamera) {

            devicePositon = AVCaptureDevicePositionBack;

        }else{

            devicePositon = AVCaptureDevicePositionFront;

        }

        for (AVCaptureDevice *device in [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo]) {

            if ([device position] == devicePositon) {

                [self.previewLayer.session beginConfiguration];

                AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:device error:nil];

                for (AVCaptureInput *oldInput in self.previewLayer.session.inputs) {

                    [[self.previewLayer session] removeInput:oldInput];

                }

                [self.previewLayer.session addInput:input];

                [self.previewLayer.session commitConfiguration];

                break;

                

            }

        }

        

        

        

        

        _isUsingFrontFacingCamera = !_isUsingFrontFacingCamera;

    }

  • 相关阅读:
    java Servlet小结
    Java 自定义客户端与服务器
    JAVA IO流总结
    java udp与tcp
    tomcat作为服务器的配置
    Linux
    Git -- 如何删除本地仓库
    ASP.NET Core 基础 Startup 类
    ASP.NET Core解说之Middleware(中间件)
    一、Redis安装 Redis学习记录
  • 原文地址:https://www.cnblogs.com/daxueshan/p/5808677.html
Copyright © 2020-2023  润新知