版权所有,禁止匿名转载;禁止商业使用。
利用AVFoundation框架比第三方框架识别二维码更快速,并且第三方框架不支持64位,本篇文章使用AVFoundation框架来完成二维码读取
二维码的读取
1.创建一个捕捉会话
let session = AVCaptureSession()
2.设置输入设备
let device = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo) guard let deviceInput = try? AVCaptureDeviceInput(device: device) else { print("没有获取到输入设备") return } session.addInput(deviceInput)
3.设置输出设备和代理
let output = AVCaptureMetadataOutput() output.setMetadataObjectsDelegate(self, queue: dispatch_get_main_queue()) session.addOutput(output) output.metadataObjectTypes = output.availableMetadataObjectTypes
4.设置扫描范围为扫描框内,注意,设置范围的x,y轴是于iOS的x,y轴相反的
let rect = UIScreen.mainScreen().bounds // containerView是扫描框控件 let containerRect = containerView.frame output.rectOfInterest = CGRect(x: containerRect.origin.y / rect.size.height , y: containerRect.origin.x / rect.size.width, width: containerRect.size.height / rect.size.height, height: containerRect.size.width / rect.size.width)
5.添加预览图层并开始扫描
let previewLayer = AVCaptureVideoPreviewLayer(session: session) previewLayer.frame = UIScreen.mainScreen().bounds view.layer.insertSublayer(previewLayer, atIndex: 0) self.previewLayer = previewLayer session.startRunning()
6.在代理方法中获得扫描的数据并设置将获得的数据显示出来
func captureOutput(captureOutput: AVCaptureOutput!, didOutputMetadataObjects metadataObjects: [AnyObject]!, fromConnection connection: AVCaptureConnection!)
从相册读取二维码
1.创建照片源
if !UIImagePickerController.isSourceTypeAvailable(.PhotoLibrary) { print("照片库不可用") return } // 创建选择照片的控制器 let ipc = UIImagePickerController() // 设置照片源 ipc.sourceType = .PhotoLibrary // 设置代理 ipc.delegate = self // 弹出控制器 presentViewController(ipc, animated: true, completion: nil)
2.在代理方法中拿到照片并读取
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) { // 拿到图片 guard let image = info[UIImagePickerControllerOriginalImage] as? UIImage else { print("没有获取到照片") return } // 创建扫描器 let detector = CIDetector(ofType: CIDetectorTypeQRCode, context: nil, options: nil) // 扫描结果 guard let ciImage = CIImage(image: image) else { print("转ciImage失败") return } let features = detector.featuresInImage(ciImage) // 遍历扫描结果 for f in features { guard let feature = f as? CIQRCodeFeature else { continue } print(feature.messageString) } }
生成二维码,并且在二维码中心画上头像
override func viewDidLoad() { super.viewDidLoad() // 创建滤镜 let filter = CIFilter(name: "CIQRCodeGenerator") // 恢复默认设置 filter?.setDefaults() // 设置数据 let qrcodeInfo = "http://www.jianshu.com/users/d4396e83f3b4/latest_articles" guard let qrcodeInfoData = qrcodeInfo.dataUsingEncoding(NSUTF8StringEncoding) else { return } filter?.setValue(qrcodeInfoData, forKeyPath: "inputMessage") // 获取生成的图片 guard let outputImage = filter?.outputImage else { return } // 设置图片 let image = scaleImage(outputImage) // 在二维码中画上头像 qrcodeView.image = drawIconView(image, iconName: "111") } private func drawIconView(image : UIImage, iconName : String) -> UIImage { // 开启图片上下文 UIGraphicsBeginImageContext(image.size) // 将图片画到上下文中 image.drawInRect(CGRect(origin: CGPointZero, size: image.size)) // 根据图标名称生成图片,并且将图片画到上下文中 let iconImage = UIImage(named: iconName) let width : CGFloat = 60 let height : CGFloat = 60 let x = (image.size.width - width) * 0.5 let y = (image.size.height - height) * 0.5 iconImage?.drawInRect(CGRect(x: x, y: y, width: width, height: height)) // 获取图片 let drawImage = UIGraphicsGetImageFromCurrentImageContext() // 关闭上下文 UIGraphicsEndImageContext() return drawImage } // 放大生成的二维码 private func scaleImage(ciImage : CIImage) -> UIImage { // 创建放大的系数 let tranform = CGAffineTransformMakeScale(10, 10) // 根据放大系数放大的图片 let newImage = ciImage.imageByApplyingTransform(tranform) // 返回生成好的图片 return UIImage(CIImage: newImage) }