Swift - 二维码QRCode的读取(从图片读取 ,或通过摄像头扫描)

来源:互联网 发布:大数据前十大公司排名 编辑:程序博客网 时间:2024/04/28 03:06
1,直接读取图片中的二维码
使用 CIDetector 可以很方便的检测并读取二维码。下面是一个从 UIImage 中读取二维码的样例,我们要把图片上所有的二维码信息都打印出来。

代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import UIKit
 
class ViewControllerUIViewController {
 
    override func viewDidLoad() {
        super.viewDidLoad()
 
        let qrcodeImg =  UIImage(named: "codeBg.png")
        let ciImage:CIImage=CIImage(image:qrcodeImg!)!
         
        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)
        }
    }
 
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
}

2,从相册中选择图片读取二维码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
import UIKit
 
class ViewControllerUIViewControllerUIImagePickerControllerDelegate,
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[UIImagePickerControllerOriginalImageasUIImage
        
        //二维码读取
        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 属性,可以设置探测探测区域。同时给这个探测区域添加个方框,只有在框中的二维码才会被扫描到。

代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
import UIKit
import AVFoundation
 
class ViewControllerUIViewControllerAVCaptureMetadataOutputObjectsDelegate,
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] asAVMetadataMachineReadableCodeObject
            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()
    }
}

0 0