2000字范文,分享全网优秀范文,学习好帮手!
2000字范文 > iOS_从相机或相册里扫描二维码或条形码

iOS_从相机或相册里扫描二维码或条形码

时间:2021-07-11 22:56:57

相关推荐

iOS_从相机或相册里扫描二维码或条形码

文章目录

1. 从相机里扫描1.1 申请相机权限1.2 创建Scanner1.3 开始扫描1.4 处理扫描结果 2. 从相册里扫描2.1 获取相册权限2.2 打开相册2.3 获得选择结果2.4 解析相片中的二维码或条形码

1. 从相机里扫描

1.1 申请相机权限

导入:import AVFoundation在项目的Info.plist文件里添加Privacy - Camera Usage Descriptio描述申请使用相机权限。查询相机权限:AVCaptureDevice.authorizationStatus(for: .video)权限类型:AVAuthorizationStatus

notDetermined 未申请restricted受限制denied已拒绝authorized已授权

请求相机权限,系统弹出授权申请提示:

AVCaptureDevice.requestAccess(for: .video) {(status) in// handle request result}

1.2 创建Scanner

获得设备:

guard let device = AVCaptureDevice.default(for: .video) else {print("device error")return}

创建input:

let input: AVCaptureDeviceInputdo {input = try AVCaptureDeviceInput(device: device)} catch {print("input error")return}if self.captureSession.canAddInput(input) {self.captureSession.addInput(input)} else {print("session can't add input")return}

创建 output:

let output = AVCaptureMetadataOutput()if self.captureSession.canAddOutput(output) {// Tips: add output must before of set outputself.captureSession.addOutput(output)} else {print("session can't add output")return}// Set metadata identification type qr: QR code; Other: Barcode// 设置扫描类型(qr:二维码,其他:条形码)let hopeSupportTypes = [AVMetadataObject.ObjectType.qr,AVMetadataObject.ObjectType.ean13,AVMetadataObject.ObjectType.ean8,AVMetadataObject.ObjectType.pdf417]var types: [AVMetadataObject.ObjectType] = []for type in hopeSupportTypes {if output.availableMetadataObjectTypes.contains(type) {types.append(type)}}output.setMetadataObjectsDelegate(self, queue: DispatchQueue.main)output.metadataObjectTypes = types output.rectOfInterest = CGRect(x: 0, y: 0,width: self.view.bounds.size.width,height: self.view.bounds.size.height)

设置预览视图:

let previewLayer = AVCaptureVideoPreviewLayer(session: self.captureSession)previewLayer.frame = scanView.layer.boundspreviewLayer.videoGravity = .resizeAspectFillscanView.layer.addSublayer(previewLayer)

1.3 开始扫描

Tips: 不能在主线程中扫描,否则会无法响应用户操作,导致卡死现象

DispatchQueue.global(qos: .userInitiated).async {self.captureSession.startRunning()}

1.4 处理扫描结果

遵循AVCaptureMetadataOutputObjectsDelegate协议,实现扫描回调方法:

func metadataOutput(_ output: AVCaptureMetadataOutput,didOutput metadataObjects: [AVMetadataObject],from connection: AVCaptureConnection) {guard let metadataObject = metadataObjects.first else {captureSession.stopRunning()return}guard let readableObject = metadataObject as? AVMetadataMachineReadableCodeObject else {print("as? AVMetadataMachineReadableCodeObject faliue")return}guard let stringValue = readableObject.stringValue else {print("stringValue faliue")return}AudioServicesPlaySystemSound(SystemSoundID(kSystemSoundID_Vibrate))print("scan result: \(stringValue)") // print resultcaptureSession.stopRunning()}

2. 从相册里扫描

2.1 获取相册权限

导入:import Photos在项目的Info.plist文件里添加Privacy - Photo Library Usage Description描述申请访问相册权限。查询相机权限:PHPhotoLibrary.authorizationStatus()权限类型:PHAuthorizationStatus

notDetermined 未申请restricted受限制denied已拒绝authorized已授权limited 已授权有限库访问

请求相册权限,系统弹出授权申请提示:

PHPhotoLibrary.requestAuthorization {(status) in// handle request result}

2.2 打开相册

Tips: 打开相册必须在主线程中执行

/// have photos permissionDispatchQueue.main.async {self.openPhotoLabrary()}private func openPhotoLabrary() {let picker = UIImagePickerController()picker.title = "Photos"picker.delegate = selfpicker.allowsEditing = truepicker.sourceType = .photoLibrarypicker.navigationBar.barStyle = .defaultself.present(picker, animated: true, completion: nil)}

2.3 获得选择结果

遵循UIImagePickerControllerDelegateUINavigationControllerDelegate协议,并实现选中相片后触发的协议方法:

func imagePickerController(_ picker: UIImagePickerController,didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {dismiss(animated: true)guard let image = info[.originalImage] as? UIImage else {print("choose not image")return}parseBarCode(image: image)}

2.4 解析相片中的二维码或条形码

导入:import Vision

/// parse qrCode or barCodeprivate func parseBarCode(image: UIImage) {guard let cgimg = image.cgImage else {return}let request = VNDetectBarcodesRequest {req, err inif let error = err {print("parseBarCode error: \(error)")return}self.handleResults(req.results)}let handler = VNImageRequestHandler(cgImage: cgimg)do {try handler.perform([request])} catch {print("parseBarCode error: \(error)")}}private func handleResults(_ result: [VNObservation]?) {guard let results = result, results.count > 0 else {print("parseBarCode result is nil: \(String(describing: result))")return}for result in results {self.handleResult(result)}}private func handleResult(_ result: VNObservation) {guard let barcode = result as? VNBarcodeObservation,let value = barcode.payloadStringValue else {print("handleResult covert to string error: \(result)")return}if barcode.symbology == .qr {print("二维码: \(value)")} else {print("条形码: \(value), \(barcode.symbology.rawValue)")}}

github demo

参考:

iOS16 Swift二维码/条形码扫描+相册获取识别

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。