iOS调用相机无感抓拍
2021-03-24 本文已影响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