利用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)
}