杭州网络科技网站建设,东莞建工集团,网络推广怎么找客户资源,新乡网站推广公司文章目录1. 从相机里扫描1.1 申请相机权限1.2 创建Scanner1.3 开始扫描1.4 处理扫描结果2. 从相册里扫描2.1 获取相册权限2.2 打开相册2.3 获得选择结果2.4 解析相片中的二维码或条形码1. 从相机里扫描
1.1 申请相机权限
导入#xff1a; import AVFoundation在项目的 Info.…
文章目录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: AVCaptureDeviceInput
do {input try AVCaptureDeviceInput(device: device)
} catch {print(input error)return
}
if self.captureSession.canAddInput(input) {self.captureSession.addInput(input)
} else {print(session cant 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 cant 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.bounds
previewLayer.videoGravity .resizeAspectFill
scanView.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 permission
DispatchQueue.main.async {self.openPhotoLabrary()
}private func openPhotoLabrary() {let picker UIImagePickerController()picker.title Photospicker.delegate selfpicker.allowsEditing truepicker.sourceType .photoLibrarypicker.navigationBar.barStyle .defaultself.present(picker, animated: true, completion: nil)
}2.3 获得选择结果
遵循 UIImagePickerControllerDelegate 和 UINavigationControllerDelegate 协议并实现选中相片后触发的协议方法
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 barCode
private 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二维码/条形码扫描相册获取识别