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

1,直接读取图片中的二维码
使用  CIDetector 可以很方便的检测并读取二维码。下面是一个从  UIImage 中读取二维码的样例,我们要把图片上所有的二维码信息都打印出来。
原文:Swift - 二维码QRCode的读取(从图片读取 ,或通过摄像头扫描)


代码如下:
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
import  UIKit
 
class  ViewController UIViewController  {
 
     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
http://www.hangge.com
http://www.hangge.com
可以看到两个二维码都成功的读取到了。

(注:这个我原来用模拟器一直检测不到二维码,使用真机调试就没问题。 感谢网友“落叶”的提醒,模拟器选iphone5s及以上设备也是可以检测到的。) 

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  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 属性,可以设置探测探测区域。同时给这个探测区域添加个方框,只有在框中的二维码才会被扫描到。

效果图如下:
原文:Swift - 二维码QRCode的读取(从图片读取 ,或通过摄像头扫描)

代码如下:
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  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()
     }
}

原文出自: www.hangge.com   转载请保留原文链接: http://www.hangge.com/blog/cache/detail_915.html
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值