基于swift3.0
1.扫描二维码
设置扫描会话,图层和输入输出
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
|
//设置捕捉设备 let device = avcapturedevice.defaultdevice(withmediatype: avmediatypevideo) do { //设置设备输入输出 let input = try avcapturedeviceinput(device: device) let output = avcapturemetadataoutput() output.setmetadataobjectsdelegate(self, queue: dispatchqueue.main) //设置会话 let scansession = avcapturesession() scansession.cansetsessionpreset(avcapturesessionpresethigh) if scansession.canaddinput(input) { scansession.addinput(input) } if scansession.canaddoutput(output) { scansession.addoutput(output) } //设置扫描类型(二维码和条形码) output.metadataobjecttypes = [ avmetadataobjecttypeqrcode, avmetadataobjecttypecode39code, avmetadataobjecttypecode128code, avmetadataobjecttypecode39mod43code, avmetadataobjecttypeean13code, avmetadataobjecttypeean8code, avmetadataobjecttypecode93code] //预览图层 let scanpreviewlayer = avcapturevideopreviewlayer(session:scansession) scanpreviewlayer?.videogravity = avlayervideogravityresizeaspectfill scanpreviewlayer?.frame = view.layer.bounds view.layer.insertsublayer(scanpreviewlayer!, at: 0) //自动对焦 if (device?.isfocusmodesupported(.autofocus))! { do { try input.device.lockforconfiguration() } catch { } input.device.focusmode = .autofocus input.device.unlockforconfiguration() } //设置扫描区域 notificationcenter. default .addobserver(forname: nsnotification.name.avcaptureinputportformatdescriptiondidchange, object: nil, queue: nil, using : {[weak self] (noti) in output.rectofinterest = (scanpreviewlayer?.metadataoutputrectofinterest( for : self!.scanpane.frame))! }) //保存会话 self.scansession = scansession } catch { //摄像头不可用 tool.confirm(title: "温馨提示" , message: "摄像头不可用" , controller: self) return } |
开始扫描
1
2
3
4
|
if !scansession.isrunning { scansession.startrunning() } |
扫描结果在代理方法中
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
|
//扫描捕捉完成 extension scancodeviewcontroller : avcapturemetadataoutputobjectsdelegate { func captureoutput(_ captureoutput: avcaptureoutput!, didoutputmetadataobjects metadataobjects: [any]!, from connection: avcaptureconnection!) { //停止扫描 self.scanline.layer.removeallanimations() self.scansession!.stoprunning() //播放声音 tool.playalertsound(sound: "noticemusic.caf" ) //扫完完成 if metadataobjects.count > 0 { if let resultobj = metadataobjects.first as? avmetadatamachinereadablecodeobject { tool.confirm(title: "扫描结果" , message: resultobj.stringvalue, controller: self,handler: { (_) in //继续扫描 self.startscan() }) } } } } |
2.二维码生成
通过滤镜生成cgimage
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
|
//2.二维码滤镜 let contentdata = self.data( using : string.encoding.utf8) let fileter = cifilter(name: "ciqrcodegenerator" ) fileter?.setvalue(contentdata, forkey: "inputmessage" ) fileter?.setvalue( "h" , forkey: "inputcorrectionlevel" ) let ciimage = fileter?.outputimage //3.颜色滤镜 let colorfilter = cifilter(name: "cifalsecolor" ) colorfilter?.setvalue(ciimage, forkey: "inputimage" ) colorfilter?.setvalue(cicolor(cgcolor: qrcodecolor.cgcolor), forkey: "inputcolor0" ) // 二维码颜色 colorfilter?.setvalue(cicolor(cgcolor: qrcodebgcolor.cgcolor), forkey: "inputcolor1" ) // 背景色 //4.生成处理 let outimage = colorfilter!.outputimage let scale = qrcodesize / outimage!.extent.size.width; let transform = cgaffinetransform(scalex: scale, y: scale) let transformimage = colorfilter!.outputimage!.applying(transform) |
通过cgimage生成uiimage
1
|
let image = uiimage(ciimage: ciimage) |
绘制logo和边框
1
2
3
4
5
6
7
8
9
10
11
12
13
|
// 绘制logo uigraphicsbeginimagecontextwithoptions(image.size, false , uiscreen.main.scale) image.draw(in: cgrect(x: 0, y: 0, width: image.size.width, height: image.size.height)) //线框 let logoborderlineimagae = qrcodelogo.getroundrectimage(size: logowidth, radius: radius, borderwidth: borderlinewidth, bordercolor: borderlinecolor) //边框 let logoborderimagae = logoborderlineimagae.getroundrectimage(size: logowidth, radius: radius, borderwidth: boderwidth, bordercolor: bordercolor) logoborderimagae.draw(in: logoframe) let qrcodeimage = uigraphicsgetimagefromcurrentimagecontext() uigraphicsendimagecontext() |
封装接口:
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
|
/** 1.生成二维码 - returns: 黑白普通二维码(大小为300) */ func generateqrcode() -> uiimage /** 2.生成二维码 - parameter size: 大小 - returns: 生成带大小参数的黑白普通二维码 */ func generateqrcodewithsize(size:cgfloat?) -> uiimage /** 3.生成二维码 - parameter logo: 图标 - returns: 生成带logo二维码(大小:300) */ func generateqrcodewithlogo(logo:uiimage?) -> uiimage /** 4.生成二维码 - parameter size: 大小 - parameter logo: 图标 - returns: 生成大小和logo的二维码 */ func generateqrcode(size:cgfloat?,logo:uiimage?) -> uiimage /** 5.生成二维码 - parameter size: 大小 - parameter color: 颜色 - parameter bgcolor: 背景颜色 - parameter logo: 图标 - returns: 带logo、颜色二维码 */ func generateqrcode(size:cgfloat?,color:uicolor?,bgcolor:uicolor?,logo:uiimage?) -> uiimage /** 6.生成二维码 - parameter size: 大小 - parameter color: 颜色 - parameter bgcolor: 背景颜色 - parameter logo: 图标 - parameter radius: 圆角 - parameter borderlinewidth: 线宽 - parameter borderlinecolor: 线颜色 - parameter boderwidth: 带宽 - parameter bordercolor: 带颜色 - returns: 自定义二维码 */ func generateqrcode(size:cgfloat?,color:uicolor?,bgcolor:uicolor?,logo:uiimage?,radius:cgfloat,borderlinewidth:cgfloat?,borderlinecolor:uicolor?,boderwidth:cgfloat?,bordercolor:uicolor?) -> uiimage 使用 dispatchqueue.global().async { let image = content.generateqrcodewithlogo(logo: self.logoimageview.image) dispatchqueue.main.async(execute: { self.qrcodeimageview.image = image }) } |
3.识别二维码
通过cidetector识别二维码
cidetector用于分析ciimage,以得到cifeature,每个cidetector都要用一个探测器类型(nsstring)来初始化。这个类型用于告诉探测器要找什么特征
1.识别图片二维码
1
2
3
4
5
6
7
8
9
10
|
func recognizeqrcode() -> string? { let detector = cidetector(oftype: cidetectortypeqrcode, context: nil, options: [cidetectoraccuracy : cidetectoraccuracyhigh]) let features = detector?.features(in: coreimage.ciimage(cgimage: self.cgimage!)) guard (features?.count)! > 0 else { return nil } let feature = features?.first as? ciqrcodefeature return feature?.messagestring } |
使用实例
1
2
3
4
5
6
7
8
|
dispatchqueue.global().async { let recognizeresult = self.sourceimage?.recognizeqrcode() let result = recognizeresult?.characters.count > 0 ? recognizeresult : "无法识别" dispatchqueue.main.async { tool.confirm(title: "扫描结果" , message: result, controller: self) self.activityindicatoryview.stopanimating() } } |
本文demo地址:qrcode.rar
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。
原文链接:http://www.jianshu.com/p/93d7a4b9b8f6