美文网首页很常
iOS调用相机无感抓拍

iOS调用相机无感抓拍

作者: 倪大头 | 来源:发表于2021-03-24 12:02 被阅读0次

    UIImagePickerController虽然有takePicture方法,但会弹出拍照界面,直接用AVCaptureDevice调用摄像头就可以进行无感抓拍

    导入AVFoundation框架

    #import <AVFoundation/AVFoundation.h>
    

    需要的几个类:

    // 摄像头
    @property (nonatomic, strong) AVCaptureDevice *device;
    
    // 输入
    @property (nonatomic, strong) AVCaptureDeviceInput *input;
    
    // 输出图片
    @property (nonatomic, strong) AVCaptureStillImageOutput *imgOutput;
    
    // session
    @property (nonatomic, strong) AVCaptureSession *session;
    

    用AVCaptureSession启动采集设备AVCaptureDevice拍照并输出图片AVCaptureStillImageOutput

    初始化采集设备,这里我调用的前置摄像头:

    self.device = [self getCameraWithPosition:AVCaptureDevicePositionFront];
    

    获取摄像头的方法:

    - (AVCaptureDevice *)getCameraWithPosition:(AVCaptureDevicePosition)position {
        NSArray *devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];
        for (AVCaptureDevice *device in devices) {
            if (device.position == position) {
                return device;
            }
        }
        return nil;
    }
    

    初始化输入类:

    self.input = [[AVCaptureDeviceInput alloc]initWithDevice:self.device error:nil];
    

    初始化图片输出类:

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

    初始化session:

    self.session = [[AVCaptureSession alloc]init];
    // 获取的图片大小
    self.session.sessionPreset = AVCaptureSessionPreset1280x720;
    // 绑定输入输出类
    if ([self.session canAddInput:self.input]) {
        [self.session addInput:self.input];
    }
    if ([self.session canAddOutput:self.imgOutput]) {
        [self.session addOutput:self.imgOutput];
    }
    

    关闭闪光灯:

    if ([self.device lockForConfiguration:nil]) {
        // 关闭闪光灯
        self.device.flashMode = AVCaptureFlashModeOff;
        [self.device unlockForConfiguration];
    }
    

    开始采集:

    // 开始采集
    [self.session startRunning];
    

    拍照:

    AVCaptureConnection *connection = [self.imgOutput connectionWithMediaType:AVMediaTypeVideo];
    if (connection) {
        [self.imgOutput captureStillImageAsynchronouslyFromConnection:connection completionHandler:^(CMSampleBufferRef  _Nullable imageDataSampleBuffer, NSError * _Nullable error) {
            if (imageDataSampleBuffer) {
                NSData *imgData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageDataSampleBuffer];
                UIImage *image = [UIImage imageWithData:imgData];
                self.imageView.image = image;
            }
        }];
    }
    

    停止采集:

    if ([self.session isRunning]) {
        [self.session stopRunning];
    }
    

    完整代码:

    #import "ViewController.h"
    #import <AVFoundation/AVFoundation.h>
    
    @interface ViewController ()
    
    // 摄像头
    @property (nonatomic, strong) AVCaptureDevice *device;
    
    // 输入
    @property (nonatomic, strong) AVCaptureDeviceInput *input;
    
    // 输出图片
    @property (nonatomic, strong) AVCaptureStillImageOutput *imgOutput;
    
    // session
    @property (nonatomic, strong) AVCaptureSession *session;
    
    // 图片展示
    @property (nonatomic, strong) UIImageView *imageView;
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        
        self.view.backgroundColor = UIColor.whiteColor;
        
        [self configCamera];
        [self initSubviews];
    }
    
    - (void)configCamera {
        self.device = [self getCameraWithPosition:AVCaptureDevicePositionFront];
        self.input = [[AVCaptureDeviceInput alloc]initWithDevice:self.device error:nil];
        
        self.imgOutput = [[AVCaptureStillImageOutput alloc]init];
        
        self.session = [[AVCaptureSession alloc]init];
        // 获取的图片大小
        self.session.sessionPreset = AVCaptureSessionPreset1280x720;
        if ([self.session canAddInput:self.input]) {
            [self.session addInput:self.input];
        }
        if ([self.session canAddOutput:self.imgOutput]) {
            [self.session addOutput:self.imgOutput];
        }
        
        if ([self.device lockForConfiguration:nil]) {
            // 关闭闪光灯
            self.device.flashMode = AVCaptureFlashModeOff;
            [self.device unlockForConfiguration];
        }
        
        // 开始采集
        [self.session startRunning];
    }
    
    - (AVCaptureDevice *)getCameraWithPosition:(AVCaptureDevicePosition)position {
        NSArray *devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];
        for (AVCaptureDevice *device in devices) {
            if (device.position == position) {
                return device;
            }
        }
        return nil;
    }
    
    - (void)initSubviews {
        UIButton *button = [[UIButton alloc]initWithFrame:CGRectMake(50, 100, 290, 50)];
        button.backgroundColor = UIColor.blueColor;
        [button setTitle:@"拍照" forState:UIControlStateNormal];
        [button setTitleColor:UIColor.whiteColor forState:UIControlStateNormal];
        [self.view addSubview:button];
        [button addTarget:self action:@selector(takePhoto) forControlEvents:UIControlEventTouchUpInside];
        
        self.imageView = [[UIImageView alloc]initWithFrame:CGRectMake(50, CGRectGetMaxY(button.frame) + 50, 290, 300)];
        self.imageView.contentMode = UIViewContentModeScaleAspectFill;
        self.imageView.clipsToBounds = YES;
        [self.view addSubview:self.imageView];
    }
    
    // 拍照
    - (void)takePhoto {
        AVCaptureConnection *connection = [self.imgOutput connectionWithMediaType:AVMediaTypeVideo];
        if (connection) {
            [self.imgOutput captureStillImageAsynchronouslyFromConnection:connection completionHandler:^(CMSampleBufferRef  _Nullable imageDataSampleBuffer, NSError * _Nullable error) {
                if (imageDataSampleBuffer) {
                    NSData *imgData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageDataSampleBuffer];
                    UIImage *image = [UIImage imageWithData:imgData];
                    self.imageView.image = image;
                }
            }];
        }
    }
    
    - (void)dealloc {
        if ([self.session isRunning]) {
            [self.session stopRunning];
        }
    }
    
    @end
    

    相关文章

      网友评论

        本文标题:iOS调用相机无感抓拍

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