1,直接讀取圖片中的二維碼
使用 CIDetector 可以很方便的檢測並讀取二維碼。下面是一個從 UIImage 中讀取二維碼的樣例,我們要把圖片上所有的二維碼信息都打印出來。代碼如下 復制代碼 import UIKit
控制台輸出如下:
掃描到二維碼個數:2
http://www.111cn.net
http://www.111cn.net
可以看到兩個二維碼都成功的讀取到了。
(注:這個我原來用模擬器一直檢測不到二維碼,使用真機調試就沒問題。感謝網友“落葉”的提醒,模擬器選iphone5s及以上設備也是可以檢測到的。)
2,從相冊中選擇圖片讀取二維碼
代碼如下 復制代碼import UIKit
class ViewController: UIViewController, UIImagePickerControllerDelegate,
UINavigationControllerDelegate {
override func viewDidLoad() {
super.viewDidLoad()
}
//選取相冊
@IBAction func fromAlbum(sender: AnyObject) {
//判斷設置是否支持圖片庫
if UIImagePickerController.isSourceTypeAvailable(.PhotoLibrary){
//初始化圖片控制器
let picker = UIImagePickerController()
//設置代理
picker.delegate = self
//指定圖片控制器類型
picker.sourceType = UIImagePickerControllerSourceType.PhotoLibrary
//彈出控制器,顯示界面
self.presentViewController(picker, animated: true, completion: {
() -> Void in
})
}else{
print("讀取相冊錯誤")
}
}
//選擇圖片成功後代理
func imagePickerController(picker: UIImagePickerController,
didFinishPickingMediaWithInfo info: [String : AnyObject]) {
//獲取選擇的原圖
let image = info[UIImagePickerControllerOriginalImage] as! UIImage
//二維碼讀取
let ciImage:CIImage=CIImage(image:image)!
let context = CIContext(options: nil)
let detector:CIDetector=CIDetector(ofType: CIDetectorTypeQRCode,
context: context, options: [CIDetectorAccuracy:CIDetectorAccuracyHigh])
let features=detector.featuresInImage(ciImage)
print("掃描到二維碼個數:\(features.count)")
//遍歷所有的二維碼,並框出
for feature in features as! [CIQRCodeFeature] {
print(feature.messageString)
}
//圖片控制器退出
picker.dismissViewControllerAnimated(true, completion: {
() -> Void in
})
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
3,使用攝像頭掃描讀取二維碼
(1)掃描主要使用的是 AVFoundation,用起來方便簡單
(2)通過 AVCaptureMetadataOutput 的 rectOfInterest 屬性,可以設置探測探測區域。同時給這個探測區域添加個方框,只有在框中的二維碼才會被掃描到。
效果圖如下:
代碼如下 復制代碼
import UIKit
import AVFoundation
class ViewController: UIViewController, AVCaptureMetadataOutputObjectsDelegate,
UIAlertViewDelegate{
var scanRectView:UIView!
var device:AVCaptureDevice!
var input:AVCaptureDeviceInput!
var output:AVCaptureMetadataOutput!
var session:AVCaptureSession!
var preview:AVCaptureVideoPreviewLayer!
override func viewDidLoad() {
super.viewDidLoad()
}
//通過攝像頭掃描
@IBAction func fromCamera(sender: AnyObject) {
do{
self.device = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo)
self.input = try AVCaptureDeviceInput(device: device)
self.output = AVCaptureMetadataOutput()
output.setMetadataObjectsDelegate(self, queue: dispatch_get_main_queue())
self.session = AVCaptureSession()
if UIScreen.mainScreen().bounds.size.height<500 {
self.session.sessionPreset = AVCaptureSessionPreset640x480
}else{
self.session.sessionPreset = AVCaptureSessionPresetHigh
}
self.session.addInput(self.input)
self.session.addOutput(self.output)
self.output.metadataObjectTypes = [AVMetadataObjectTypeQRCode]
//計算中間可探測區域
let windowSize:CGSize = UIScreen.mainScreen().bounds.size;
let scanSize:CGSize = CGSizeMake(windowSize.width*3/4,
windowSize.width*3/4);
var scanRect:CGRect = CGRectMake((windowSize.width-scanSize.width)/2,
(windowSize.height-scanSize.height)/2, scanSize.width, scanSize.height);
//計算rectOfInterest 注意x,y交換位置
scanRect = CGRectMake(scanRect.origin.y/windowSize.height,
scanRect.origin.x/windowSize.width,
scanRect.size.height/windowSize.height,
scanRect.size.width/windowSize.width);
//設置可探測區域
self.output.rectOfInterest = scanRect
self.preview = AVCaptureVideoPreviewLayer(session:self.session)
self.preview.videoGravity = AVLayerVideoGravityResizeAspectFill
self.preview.frame = UIScreen.mainScreen().bounds
self.view.layer.insertSublayer(self.preview, atIndex:0)
//添加中間的探測區域綠框
self.scanRectView = UIView();
self.view.addSubview(self.scanRectView)
self.scanRectView.frame = CGRectMake(0, 0, scanSize.width, scanSize.height);
self.scanRectView.center = CGPointMake(
CGRectGetMidX(UIScreen.mainScreen().bounds),
CGRectGetMidY(UIScreen.mainScreen().bounds));
self.scanRectView.layer.borderColor = UIColor.greenColor().CGColor
self.scanRectView.layer.borderWidth = 1;
//開始捕獲
self.session.startRunning()
}catch _ as NSError{
//打印錯誤消息
let errorAlert = UIAlertView(title: "提醒",
message: "請在iPhone的\"設置-隱私-相機\"選項中,允許本程序訪問您的相機",
delegate: self,
cancelButtonTitle: "確定")
errorAlert.show()
}
}
//攝像頭捕獲
func captureOutput(captureOutput: AVCaptureOutput!,
didOutputMetadataObjects metadataObjects: [AnyObject]!,
fromConnection connection: AVCaptureConnection!) {
var stringValue:String?
if metadataObjects.count > 0 {
let metadataObject = metadataObjects[0] as! AVMetadataMachineReadableCodeObject
stringValue = metadataObject.stringValue
if stringValue != nil{
self.session.stopRunning()
}
}
self.session.stopRunning()
//輸出結果
let alertView = UIAlertView(title: "二維碼", message: stringValue,
delegate: self, cancelButtonTitle: "確定")
alertView.show()
}
//消息框確認後消失
func alertView(alertView: UIAlertView, willDismissWithButtonIndex buttonIndex: Int) {
//繼續掃描
self.session.startRunning()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}