iOS开发 - 系统自带框架实现扫一扫功能

news2024/11/24 6:02:32

iOS 扫一扫

利用系统自带框架实现扫一扫功能

一 项目配置

扫一扫功能相机和相册权限,在info.plist中设置询问用户是否允许访问的权限。

info.plist加入NSCameraUsageDescription、NSPhotoLibraryUsageDescription、NSPhotoLibraryAddUsageDescription


	<key>NSCameraUsageDescription</key>
	<string>开启相机权限,活动扫一扫更快捷</string>
	<key>NSPhotoLibraryAddUsageDescription</key>
	<string>添加照片需要您的同意</string>
	<key>NSPhotoLibraryUsageDescription</key>
	<string>开启照片权限,美照当然要人赞!</string>

二 扫一扫权限判断

当每次进入扫一扫页面时,需要判断是否开启了权限


/** 校验是否有相机权限 */
- (void)checkCameraAuthorizationStatus:(void(^)(BOOL granted))permissionGranted
{
    AVAuthorizationStatus videoAuthStatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
    
    switch (videoAuthStatus) {
            // 已授权
        case AVAuthorizationStatusAuthorized:
        {
            permissionGranted(YES);
        }
            break;
            // 未询问用户是否授权
        case AVAuthorizationStatusNotDetermined:
        {
            // 提示用户授权
            [AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted) {
                permissionGranted(granted);
            }];
        }
            break;
            // 用户拒绝授权或权限受限
        case AVAuthorizationStatusRestricted:
        case AVAuthorizationStatusDenied:
        {
            UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"请在”设置-隐私-相机”选项中,允许访问你的相机" message:nil delegate:nil cancelButtonTitle:@"确定" otherButtonTitles:nil];
            [alert show];
            permissionGranted(NO);
        }
            break;
        default:
            break;
    }
}

三 需要用到AVCaptureDevice、AVCaptureDeviceInput、AVCaptureMetadataOutput、AVCaptureSession、AVCaptureVideoPreviewLayer

  • AVCaptureDevice:捕获设备,通常是前置摄像头,后置摄像头,麦克风(音频输入)
  • AVCaptureDeviceInput:AVCaptureDeviceInput 代表输入设备,使用AVCaptureDevice 来初始化
  • AVCaptureMetadataOutput:输出
  • AVCaptureSession:session 把输入输出结合在一起,并开始启动捕获设备(摄像头)
  • AVCaptureVideoPreviewLayer:图像预览层,实时显示捕获的图像

设置相机


/**
 设置相机
*/
- (void)setupCamera {
    self.avDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
    self.avInput = [AVCaptureDeviceInput deviceInputWithDevice:self.avDevice error:nil];
    self.avOutput = [[AVCaptureMetadataOutput alloc]init];
    [self.avOutput setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
    
    self.avSession = [[AVCaptureSession alloc]init];
    [self.avSession setSessionPreset:AVCaptureSessionPresetHigh];
    if ([self.avSession canAddInput:self.avInput]){
        [self.avSession addInput:self.avInput];
    }
    if ([self.avSession canAddOutput:self.avOutput]){
        [self.avSession addOutput:self.avOutput];
    }
    
    // 二维码类型 AVMetadataObjectTypeQRCode
    if ([self.avOutput.availableMetadataObjectTypes containsObject:AVMetadataObjectTypeQRCode]){
        self.avOutput.metadataObjectTypes = [NSArray arrayWithObject:AVMetadataObjectTypeQRCode];
        // AVMetadataObjectTypeAztecCode 条形码
    } else{
        return ;
    }
    
    [self.avSession startRunning];//开始扫描
}

返回预览layer

/**
 显示的预览layer
 
 @return AVCaptureVideoPreviewLayer
 */
- (AVCaptureVideoPreviewLayer *)showPeviewLayer {
    self.avPreviewLayer = [AVCaptureVideoPreviewLayer layerWithSession:self.avSession];
    self.avPreviewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
    return self.avPreviewLayer;
}


开始扫描与结束扫描

/**
 开始扫描
 */
- (void)startRunning {
    [self.avSession startRunning];
}

/**
 结束扫描
 */
- (void)stopRunning {
    [self.avSession stopRunning];
}


输出扫描结果AVCaptureMetadataOutputObjectsDelegate


#pragma mark - AVCaptureMetadataOutputObjectsDelegate
- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:
(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection
{
    if ([metadataObjects count] > 0){
        AVMetadataMachineReadableCodeObject * metadataObject = [metadataObjects objectAtIndex:0];
        NSString *result = metadataObject.stringValue;//扫描出来的字符串
        NSLog(@"result:%@",result);
        
        UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"显示扫描结果" message:result delegate:nil cancelButtonTitle:@"确定" otherButtonTitles:nil];
        [alert show];
        
        [self.avSession stopRunning];//停止扫描
    }
}

使用

	self.scanConfig = [[INQrScanConfig alloc] init];
        [self.scanConfig setupCamera];
        
        AVCaptureVideoPreviewLayer *previewLayer = [self.scanConfig showPeviewLayer];
        previewLayer.frame = self.layer.bounds;
        [self.layer insertSublayer:previewLayer atIndex:0];
        [self.scanConfig startRunning];

使用

//你要设置的矩形快的frame  为  x1, y1, w1, h1.
    //那么你的 rectOfInterest 应该设置为   (y1/h, x1/w, h1/h, w1/w)
    
    CGFloat size = 260.0;
    CGRect rect = CGRectMake((KAiSysScreenWidth - size)/2, (KAiSysScreenHeight - size)/2, size, size);
    // 使用 (y1/h, x1/w, h1/h, w1/w)
    self.avOutput.rectOfInterest = CGRectMake(rect.origin.y/KAiSysScreenHeight, rect.origin.x/KAiSysScreenWidth, size/KAiSysScreenHeight, size/KAiSysScreenWidth);

结果如图:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/747332.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

java.lang.UnsatisfiedLinkError: Could not load SWT library.

java.lang.UnsatisfiedLinkError: Could not load SWT library. https://download.eclipse.org/windowbuilder/lastgoodbuild

力扣206. 反转链表

题目 给你单链表的头节点 head &#xff0c;请你反转链表&#xff0c;并返回反转后的链表。 链接&#xff1a;206. 反转链表 - 力扣&#xff08;LeetCode&#xff09; 题解 方法一&#xff1a;类似头插法 设置3个指针cur、next、newhead&#xff0c;其中cur和next指向当前链表头…

Kubernetes基础知识点

k8s可以看做是一个集群操作系统&#xff0c;能够对容器进行调度和编排。 Kubernetes中的基本对象 pod 是k8s中的最小单位&#xff0c;一个pod封装一个或者多个容器&#xff0c;存储资源。 deployment 是对pod的服务化封装&#xff0c;可以包含一个或多个pod statefulset 为…

ArcGIS处理nc数据步骤

降水温度蒸散发等气象数据通常以NC格式存储&#xff0c;可以用Matlab和ArcGIS读取数据。常为逐年逐月逐日数据。在用GIS进行数据分析时&#xff0c;需要将其转换为栅格数据。 &#xff08;1&#xff09;打开nc数据。打开GIS, ArcToolbox-Multidimension Tools-Make NetCDF Rast…

多线程高频知识点—2023

多线程高频知识点—2023 多线程的基本概念什么是线程/进程为什么在进程中还需要线程呢&#xff1f;同步与异步的区别程序计数器多线程的应用场景多线程的创建方式手写一个异步日志框架多线程线程安全问题 多线程的基本概念 什么是cpu CPU的中文名称是中央处理器&#xff0c;是…

【优选算法】—— 滑动窗口类问题

本期&#xff0c;我给大家带来的是关于滑动窗口类算法的介绍&#xff0c;并通过具体的题目帮助大家思考理解。 目录 &#xff08;一&#xff09;基本概念 &#xff08;二&#xff09;题目讲解 1、难度&#xff1a;medium 1️⃣长度最小的子数组 2️⃣找到字符串中所有字⺟…

Xcode 更新后 Version 14.3.1报错

File not found: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/arc/libarclite_iphonesimulator.a Xode版本和pod版本不一致导致&#xff0c;改成一致就可以了 放在podfile文件里,最后一个pod,和最后一个end中间 Showing Recent …

将字符串转换为字典json.loads(字符串)

【小白从小学Python、C、Java】 【计算机等考500强证书考研】 【Python-数据分析】 将字符串转换为字典 json.loads(字符串) [太阳]选择题 关于以下代码说法错误的是? import json myStr{"name":"xiaobai","age":30} print(【显示】mySt…

【论文阅读】TransCAM: Transformer Attention-based CAM Refinement for WSSS

分享一篇阅读的用于弱监督分割的论文 论文标题&#xff1a; TransCAM: Transformer Attention-based CAM Refinement for Weakly Supervised Semantic Segmentation 作者信息&#xff1a; 代码地址&#xff1a; https://github.com/liruiwen/TransCAM Abstract 大多数现有…

java判断某个字符串是否在字符串数组中的方法(4种)

1.效率最高&#xff08;最原始&#xff09; 代码如下&#xff08;示例&#xff09;&#xff1a; public class Demo { public static boolean useLoop(String[] arr, String targetValue) { for (String s : arr) { if (s.equals(targetValue)) return true; } return false; }…

图像分类——模型微调

目录 微调热狗识别获取数据集模型构建与训练 微调 热狗识别 获取数据集 import tensorflow as tf import pathlibtraindirhotdog/train testdirhotdog/test image_gentf.keras.preprocessing.image.ImageDataGenerator(rescale1/255) train_data_genimage_gen.flow_from_direc…

2023年Q2空调行业品牌数据榜单(京东商品数据)

随着夏季的来临&#xff0c;高温天气也带动部分家电行业的销售&#xff0c;以空调为代表的家电市场正逐步恢复活力。结合鲸参谋电商数据分析平台的相关数据&#xff0c;我们来分析一下2023年Q2空调市场的具体销售表现。 根据鲸参谋平台的数据显示&#xff0c;2023年4-6月份&am…

TypeScript学习(2)- ts基本类型

类型声明式Ts非常重要的一个特点&#xff0c;通过类型声明可以指定TS中变量&#xff08;参数&#xff0c;形参&#xff09;的类型。指定类型后&#xff0c;当为变量赋值时&#xff0c;ts编译器会自动检查值是否符合类型声明&#xff0c;符合则赋值&#xff0c;否则报错。 目录 …

从VAE到Diffusion生成模型详解(1):VAE

文章目录 1. 生成式模型简介2. PixelRNN/CNN3. VAE3.1 自编码器AE3.2 VAE基本原理3.3 VAE公式推导 4. 参考 1. 生成式模型简介 什么是生成式模型 给定训练集&#xff0c;产生与训练集同分布的新样本。如下图所示&#xff0c;希望学习到一个模型 p m o d e l ( x ) p_{model}(…

22 分页控件

文章目录 界面设置初始化主对话框子页面初始化 页面1枚举窗口页面2枚举进程全部代码 界面设置 ui 设置 >创建CTablCtrl > 创建页控件&#xff08;子窗口&#xff09;&#xff0c;style设置成为chlid 添加类 页面中加入listCtrl 控件 添加变量 分别添加初始化函数 初始化…

举例说明单层神经网络的工作原理

假设我们有一个简单的单层神经网络&#xff0c;用于解决一个简单的问题&#xff1a;根据一个人的年龄&#xff08;x&#xff09;来预测其收入&#xff08;y&#xff09;。在这个例子中&#xff0c;输入数据只有一个特征&#xff08;年龄&#xff09;&#xff0c;因此我们可以用…

Can转以太网网关can协议转以太网协议

YC-ETH-CAN-2 是一款用来把 CAN 总线数据转为网口数据的设备。网口支持 TCP Sever、TCP Client、UDP Sever、UDP Client、UDP Broadcast 模式&#xff0c;可以通过软件配置和网页配置。 设备提供两路 CAN 接口&#xff0c;两路 CAN 可分别配置为不同的工作模式&#xff0c;独立…

[QT编程系列-4]:C++图形用户界面编程,QT框架快速入门培训 - 2- QT程序的运行框架:信号、槽函数、对象之间的通信

目录 2. QT程序的运行框架 2.4 设计界面元素的行为&#xff1a;信号、槽函数、对象之间的通信 2.4.1 对象之间的通信 2.4.2 信号槽与消息队里区别 2.4.3 预定义信号与默认槽函数 2.4.4 预定义信号与默认槽函数&#xff1a;案例2 2.4.5 预定义信号与自定义槽函数&#xff…

【JVM系列】类加载机制和双亲委派机制(一)

使用java8 一、类加载运行全过程 当我们用java命令运行某个类的main函数启动程序时&#xff0c;首先需要通过类加载器把主类加载到JVM。 package jvmdemo;public class Math {public static final int initData 666;public static User user new User();public int comput…

立创EDA(专业版)电路设计与制作快速入门

1.新建工程的时候 &#xff08;要注意用版本控制&#xff0c;项目名&#xff0c;日期&#xff0c;版本&#xff09; 2.原理图设计环境设置 3.电源转换电路 电源是一般是5v转3.3v电路 电源主要的可以选择LLDO来降压的或者是DCDC减压 这个电路主要是用LDO来降压的 AMS1117降…