swift 二维码识别的实现
来源:互联网 发布:中文手写软件下载 编辑:程序博客网 时间:2024/05/22 00:59
本文是用系统的AVFoundation来实现二维码的扫描(注意:只支持真机)
代码地址
https://github.com/jinliyuelong/LYJSwiftDemo
1.创建viewcontroller来显示按钮进行进入扫描窗口
import UIKitimport AVFoundationclass QRcodeViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() self.setupUi() } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } func setupUi() { self.view.backgroundColor = UIColor.white let button = UIButton(frame: CGRect(x: (UIScreen.main.bounds.size.width-100) * 0.5, y: (UIScreen.main.bounds.size.height-30) * 0.5, width: 100, height: 30)) button.setTitle("扫一扫", for: UIControlState()) button.setTitleColor(UIColor.blue, for: UIControlState()) button.addTarget(self, action: #selector(QRcodeViewController.buttonAction(_:)), for: UIControlEvents.touchUpInside) self.view.addSubview(button) } func buttonAction(_ sender : AnyObject){ print("扫一扫") if self.cameraPermissions() { let scanner = ScannerViewController() self.navigationController?.pushViewController(scanner, animated: true) }else{ self.displayAlertControllerWithMessage("当前设备没有相机权限") } } /** 判断相机权限 - returns: 有权限返回true,没权限返回false */ func cameraPermissions() -> Bool{ let authStatus:AVAuthorizationStatus = AVCaptureDevice.authorizationStatus(forMediaType: AVMediaTypeVideo) debugPrint("当前的权限是=====\(authStatus.rawValue)") if(authStatus == AVAuthorizationStatus.authorized || authStatus == AVAuthorizationStatus.notDetermined) { return true }else { return false } } }2.创建扫描viewcontroller
里面有一个用来显示组件的view:ScannerBackgroundView和controller
import UIKitclass ScannerBackgroundView: UIView { var scanResult = UITextField() var scanResultPlaceHolder:String = "" //屏幕扫描区域视图 let barcodeView = UIView(frame: CGRect(x: screenWidth * 0.2, y: screenHeight * 0.15, width: screenWidth * 0.6, height: screenWidth * 0.6)) //扫描线 let scanLine = UIImageView() var timer = Timer() override init(frame: CGRect) { super.init(frame: frame) } func stopScan() { timer.invalidate() } init(frame: CGRect, scanResultPlaceHolder:String) { super.init(frame: frame) self.scanResultPlaceHolder = scanResultPlaceHolder self.setupUi() } func setupUi() { barcodeView.layer.borderWidth = 1.0 barcodeView.layer.borderColor = UIColor.white.cgColor self.addSubview(barcodeView) //设置扫描线 scanLine.frame = CGRect(x: 0, y: 0, width: barcodeView.frame.size.width, height: 5) scanLine.image = UIImage(named: "QRCodeScanLine") //添加扫描线图层 barcodeView.addSubview(scanLine) self.createBackGroundView() timer = Timer.scheduledTimer(timeInterval: 2, target: self, selector: #selector(moveScannerLayer(_:)), userInfo: nil, repeats: true) } func createBackGroundView() { let topView = UIView(frame: CGRect(x: 0, y: 0, width: screenWidth , height: screenHeight * 0.15)) let bottomView = UIView(frame: CGRect(x: 0, y: screenWidth * 0.6 + screenHeight * 0.15, width: screenWidth , height: screenHeight * 0.85 - screenWidth * 0.6)) let leftView = UIView(frame: CGRect(x: 0, y: screenHeight * 0.15, width: screenWidth * 0.2, height: screenWidth * 0.6)) let rightView = UIView(frame: CGRect(x: screenWidth * 0.8, y: screenHeight * 0.15, width: screenWidth * 0.2, height: screenWidth * 0.6)) topView.backgroundColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0.4) bottomView.backgroundColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0.4) leftView.backgroundColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0.4) rightView.backgroundColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0.4) let label = UILabel(frame: CGRect(x: 0, y: 10, width: screenWidth , height: 21)) label.textAlignment = .center label.font = UIFont.systemFont(ofSize: 14) label.textColor = UIColor.white label.text = "将二维码/条形码放入扫描框内,即自动扫描" bottomView.addSubview(label) bottomView.addSubview(scanResult) self.addscanResult() self.addSubview(topView) self.addSubview(bottomView) self.addSubview(leftView) self.addSubview(rightView) } func addscanResult() { self.scanResultP() self.scanResultF() } //设置reslut func scanResultP() { scanResult.textAlignment = .left scanResult.textColor = UIColor.white scanResult.layer.masksToBounds = true scanResult.layer.borderColor = mygrayColor.cgColor scanResult.layer.borderWidth = 1 scanResult.leftViewMode = .always scanResult.attributedPlaceholder = NSAttributedString(string: self.scanResultPlaceHolder, attributes: [NSForegroundColorAttributeName:UIColor.white ]) scanResult.layer.cornerRadius = 3 scanResult.font = UIFont.systemFont(ofSize: CGFloat(mylableSize)) } func scanResultF() { scanResult.frame = CGRect.init(x: screenWidth * 0.1, y: 10 + screenHeight * 0.1, width: screenWidth * 0.8, height: 40) } func scanResultD(reslut:String){ scanResult.text = " " + reslut } required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } //让扫描线滚动 func moveScannerLayer(_ timer : Timer) { scanLine.frame = CGRect(x: 0, y: 0, width: self.barcodeView.frame.size.width, height: 12); UIView.animate(withDuration: 2) { self.scanLine.frame = CGRect(x: self.scanLine.frame.origin.x, y: self.scanLine.frame.origin.y + self.barcodeView.frame.size.height - 10, width: self.scanLine.frame.size.width, height: self.scanLine.frame.size.height); } }}controller为:
import AVFoundationimport UIKitimport Photosclass ScannerViewController: UIViewController,AVCaptureMetadataOutputObjectsDelegate,UIImagePickerControllerDelegate,UINavigationControllerDelegate { //相机显示视图 let cameraView = ScannerBackgroundView(frame: UIScreen.main.bounds ,scanResultPlaceHolder:"请输入扫描设备") let captureSession = AVCaptureSession() override func viewDidLoad() { super.viewDidLoad() self.view.backgroundColor = UIColor.black //失效相册 //设置导航栏 let barButtonItem = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.add, target: self, action: #selector(ScannerViewController.selectPhotoFormPhotoLibrary(_:))) self.navigationItem.rightBarButtonItem = barButtonItem // self.view.addSubview(cameraView) //初始化捕捉设备(AVCaptureDevice),类型AVMdeiaTypeVideo let captureDevice = AVCaptureDevice.defaultDevice(withMediaType: AVMediaTypeVideo) let input :AVCaptureDeviceInput //创建媒体数据输出流 let output = AVCaptureMetadataOutput() //捕捉异常 do{ debugPrint("进入do循环") //创建输入流 input = try AVCaptureDeviceInput(device: captureDevice) //把输入流添加到会话 captureSession.addInput(input) //把输出流添加到会话 captureSession.addOutput(output) }catch { print("异常") } //创建串行队列 let dispatchQueue = DispatchQueue(label: "queue", attributes: []) //设置输出流的代理 output.setMetadataObjectsDelegate(self, queue: dispatchQueue) //设置输出媒体的数据类型 output.metadataObjectTypes = NSArray(array: [AVMetadataObjectTypeQRCode,AVMetadataObjectTypeEAN13Code,AVMetadataObjectTypeEAN8Code, AVMetadataObjectTypeCode128Code]) as [AnyObject] //创建预览图层 let videoPreviewLayer = AVCaptureVideoPreviewLayer(session: captureSession) //设置预览图层的填充方式 videoPreviewLayer?.videoGravity = AVLayerVideoGravityResizeAspectFill //设置预览图层的frame videoPreviewLayer?.frame = cameraView.bounds //将预览图层添加到预览视图上 cameraView.layer.insertSublayer(videoPreviewLayer!, at: 0) //设置扫描范围 output.rectOfInterest = CGRect(x: 0.2, y: 0.15, width: 0.6, height: 0.6) } override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) self.tabBarController?.tabBar.isHidden = true self.scannerStart() } func scannerStart(){ captureSession.startRunning() debugPrint("开始扫描") } func scannerStop() { captureSession.stopRunning() debugPrint("结束扫描") cameraView.stopScan() } //扫描代理方法 func captureOutput(_ captureOutput: AVCaptureOutput!, didOutputMetadataObjects metadataObjects: [Any]!, from connection: AVCaptureConnection!) { if metadataObjects != nil && metadataObjects.count > 0 { let metaData = metadataObjects.first debugPrint("进入代理方法") debugPrint("扫描结果是=======\((metaData as AnyObject).stringValue ?? " ")") // print((metaData as AnyObject).stringValue ?? " ") DispatchQueue.main.async(execute: { let result:String = (metaData as AnyObject).stringValue ?? " " self.cameraView.scanResultD(reslut: result) self.cameraView.isUserInteractionEnabled = false }) self.scannerStop() // captureSession.stopRunning() } } //从相册中选择图片 func selectPhotoFormPhotoLibrary(_ sender : AnyObject){ if self.PhotoLibraryPermissions(){ let picture = UIImagePickerController() picture.sourceType = UIImagePickerControllerSourceType.photoLibrary picture.delegate = self self.present(picture, animated: true, completion: nil) }else{ self.displayAlertControllerWithMessage("该设备没有相册权限") } } //选择相册中的图片完成,进行获取二维码信息 func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) { let image = info[UIImagePickerControllerOriginalImage] let imageData = UIImagePNGRepresentation(image as! UIImage) let ciImage = CIImage(data: imageData!) let detector = CIDetector(ofType: CIDetectorTypeQRCode, context: nil, options: [CIDetectorAccuracy: CIDetectorAccuracyLow]) let array = detector?.features(in: ciImage!) let result : CIQRCodeFeature = array!.first as! CIQRCodeFeature debugPrint("扫描结果是=======\((result.messageString))") let resultView = WebViewController() resultView.url = result.messageString self.navigationController?.pushViewController(resultView, animated: true) picker.dismiss(animated: true, completion: nil) print(result.messageString ?? "错误信息") } /** 判断相册权限 - returns: 有权限返回ture, 没权限返回false */ func PhotoLibraryPermissions() -> Bool { let library:PHAuthorizationStatus = PHPhotoLibrary.authorizationStatus() if(library == PHAuthorizationStatus.denied || library == PHAuthorizationStatus.restricted){ return false }else { return true } } }
运行效果为
注意事项:代码需要引入我写的一个扩展和工具文件
UIColor+Extension
//// UIColor+Extension.swift// MyswiftDemo//// Created by Liyanjun on 2017/1/14.// Copyright © 2017年 hand. All rights reserved.//import UIKitimport Foundationextension UIColor { /** Convenient initializer for RGB color code with default alpha 1.0 - Parameters: - red: The integer code for red - green: The integer code for green - blue: The integer code for blue */ convenience init(red: Int, green: Int, blue: Int) { assert(red >= 0 && red <= 255, "Invalid red component") assert(green >= 0 && green <= 255, "Invalid green component") assert(blue >= 0 && blue <= 255, "Invalid blue component") self.init(red: CGFloat(red) / 255.0, green: CGFloat(green) / 255.0, blue: CGFloat(blue) / 255.0, alpha: 1.0) } /** Convenient initializer for pure hex color code - Parameter hex: The hex code of color */ convenience init(hex: Int) { self.init(red: (hex >> 16) & 0xff, green: (hex >> 8) & 0xff, blue: hex & 0xff) } static let system = UIColor(hex: 0x035d9a) static let background = UIColor(hex: 0xf4f5f7) static let systemGray = UIColor(hex: 0xe2e2e2) }和工具文件
//// LYJPch.swift// Colliers-CFIM//// Created by Liyanjun on 2017/1/14.// Copyright © 2017年 hand. All rights reserved.//import UIKitimport SnapKitlet myBlackColr = UIColor(hex: 0x424243)//常用的黑色let mygrayColor = UIColor(hex: 0xb2b2b2)//常用的灰色let TitlelableColor = myBlackColr//系统常用的黑色//常用字体大小let mylableSize = 15//设置常用字体大小为16let mycommonEdge:CGFloat = 13//上下左右编剧let commonCellHeight = CGFloat(37.0 + 6)//常用tableCell的高度var keyWindow: UIWindow? { return UIApplication.shared.keyWindow}var isChinese: Bool { if let code = NSLocale.preferredLanguages.first, code.hasPrefix("zh") { return true } return false}var screenWidth:CGFloat { return UIScreen.main.bounds.width}var screenHeight:CGFloat { return UIScreen.main.bounds.height}
AVFoundation
1 0
- swift 二维码识别的实现
- swift二维码的实现
- 二维码的简单识别(Swift)
- 二维码的生成 识别 扫描 封装(Swift)
- Swift之二维码的生成、识别和扫描
- Java实现二维码的生成与识别
- Android的二维码功能实现以及长按识别二维码
- swift 扫描二维码/条形码,开启闪光灯,识别相册二维码
- 原生二维码的识别
- 20170814二维码的识别
- HTML5 实现扫描识别二维码 生成二维码
- swift 实现二维码扫描功能
- swift实现二维码扫描案例
- Android实现识别相册二维码
- QZXing+Opencv+Qt Creater实现二维码,一维码的识别
- 采用系统API实现的二维码扫描、识别和生成
- 在iOS上实现二维码功能、二维码、条形码、swift 二维码
- 识别二维码图片中 的二维码
- git log两个branch的不同
- cloudera manager下的hive权限配置
- 微信小程序 - 干货集中营
- zookeeper详解
- android中Sqlite查询的数据返回排序问题
- swift 二维码识别的实现
- Flatten Binary Tree to Linked List
- linux下 gcc编译初学者使用教程
- day11--回顾
- struts 访问servlet api (ServletActionContext 方式)
- Android开发入门——推箱子游戏开发实战(十二)
- CVM ubuntux641604 搭建L2TP VPN
- HDU 1061 Rightmost Digit (求n^n的最低位)
- 利用NodeMcu和matplotlib的温度远程实时测量显示方案