利用AVFoundation框架比第三方框架識別二維碼更快速,并且第三方框架不支持64位,本篇文章使用AVFoundation框架來完成二維碼讀取
二維碼的讀取
1.創(chuàng)建一個捕捉會話
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.創(chuàng)建照片源
if !UIImagePickerController.isSourceTypeAvailable(.PhotoLibrary) {
print("照片庫不可用")
return
}
// 創(chuàng)建選擇照片的控制器
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
}
// 創(chuàng)建掃描器
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()
// 創(chuàng)建濾鏡
let filter = CIFilter(name: "CIQRCodeGenerator")
// 恢復默認設置
filter?.setDefaults()
// 設置數據
let qrcodeInfo = "http://www.reibang.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 {
// 創(chuàng)建放大的系數
let tranform = CGAffineTransformMakeScale(10, 10)
// 根據放大系數放大的圖片
let newImage = ciImage.imageByApplyingTransform(tranform)
// 返回生成好的圖片
return UIImage(CIImage: newImage)
}