iOS|iOS 原生扫码二维码与自定义相机
实现扫码二维码与自定义相机的功能,都要用到 AVFoundation 框架。
完成功能后发现,这俩个功能在实现上大致相同,唯一不同的地方是 设置 AVCaptureSession 的 output。
扫描二维码
self.metadataOutput = [AVCaptureMetadataOutput new];
//输出的类 为 AVCaptureMetadataOutput
[self.session addOutput:self.metadataOutput];
self.metadataOutput.metadataObjectTypes = @[
AVMetadataObjectTypeQRCode,
];
[self.metadataOutput setMetadataObjectsDelegate:self queue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)];
//可以通过设置 rectOfInterest 属性,来调整扫码区域。
自定义相机
self.photoOutput = [[AVCapturePhotoOutput alloc] init];
//输出的类 为 AVCapturePhotoOutput
NSDictionary *setDic = @{
AVVideoCodecKey:AVVideoCodecTypeJPEG,
};
self.photoSettings = [AVCapturePhotoSettings photoSettingsWithFormat:setDic];
[self.photoOutput setPhotoSettingsForSceneMonitoring:self.photoSettings];
[self.session addOutput:self.photoOutput];
//可以通过设置 rectOfInterest 属性,来调整扫码区域。
具体实现如下:
首先,添加如下属性
@interface XXXCaptureViewController ()@property (nonatomic, assign)BOOL currentAuthStatus;
@property (nonatomic, strong)AVCaptureDevice *device;
@property (nonatomic, strong)AVCaptureSession *session;
@property (nonatomic, strong)AVCaptureDeviceInput *input;
@property (nonatomic, strong)AVCaptureMetadataOutput *metadataOutput;
@property (nonatomic, strong)AVCapturePhotoOutput *photoOutput;
@property (nonatomic, strong)AVCapturePhotoSettings *photoSettings;
@property (nonatomic, strong)UIButton *takephotoButton;
在使用相机前,要查看是否授权
- (BOOL)authStatus
{
AVAuthorizationStatus authStatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
if (authStatus == AVAuthorizationStatusAuthorized)
{
return YES;
}
else
{
return NO;
}
}
如果该 App 没有授权相机功能,需要请求授权
__block typeof(self) weakSelf = self;
[AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted) {if (granted == NO)
{
weakSelf.currentAuthStatus = NO;
}
else
{
weakSelf.currentAuthStatus = YES;
[weakSelf configureCaptureSessionSettting];
}
然后添加属性的相关设置
- (void)configureCaptureSessionSettting
{
if (self.currentAuthStatus == NO)
{
return;
}self.session = [AVCaptureSession new];
self.device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
NSError *error;
self.input = [AVCaptureDeviceInputdeviceInputWithDevice:self.device error:&error];
[self.session addInput:self.input];
//扫二维码
//[self.session addOutput:self.metadataOutput];
//self.metadataOutput.metadataObjectTypes = @[
//AVMetadataObjectTypeQRCode,//可以添加 AVMetadataObjectTypeCode39Code 等类型同时扫描条形码
//];
//[self.metadataOutput setMetadataObjectsDelegate:self queue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)];
//捕获照片
self.photoOutput = [[AVCapturePhotoOutput alloc] init];
NSDictionary *setDic = @{
AVVideoCodecKey:AVVideoCodecTypeJPEG,
};
self.photoSettings = [AVCapturePhotoSettings photoSettingsWithFormat:setDic];
[self.photoOutput setPhotoSettingsForSceneMonitoring:self.photoSettings];
[self.session addOutput:self.photoOutput];
AVCaptureVideoPreviewLayer* previewLayer = [AVCaptureVideoPreviewLayer layerWithSession:self.session];
previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
dispatch_async(dispatch_get_main_queue(), ^{[previewLayer setFrame:self.view.bounds];
[self.view.layer insertSublayer:previewLayer atIndex:0];
});
}
【iOS|iOS 原生扫码二维码与自定义相机】最后一步啦,开始捕获数据和停止补货。最好不要把它们放在主线程中使用。因为 startRunning 和 stopRunning 其实是一个 block,主线程调用可能会引起,UI卡顿。苹果官方具体解释:https://developer.apple.com/documentation/avfoundation/avcapturesession
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{[self.session startRunning];
});
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{[self.session stopRunning];
});
}
推荐阅读
- 2020-04-07vue中Axios的封装和API接口的管理
- iOS中的Block
- NeuVector 会是下一个爆款云原生安全神器吗()
- 原生家庭之痛与超越
- 记录iOS生成分享图片的一些问题,根据UIView生成固定尺寸的分享图片
- 2019-08-29|2019-08-29 iOS13适配那点事
- Hacking|Hacking with iOS: SwiftUI Edition - SnowSeeker 项目(一)
- iOS面试题--基础
- 接口|axios接口报错-参数类型错误解决
- iOS|iOS 笔记之_时间戳 + DES 加密