二维码识别

swift搬运工


条码识别效率低下,还没有解决

//

// ViewController.swift

// QRCodeDemo

//

// Created by xf-bao on 16/8/30.

// Copyright © 2016年 xf-bao. All rights reserved.

//

//private let kBounds = UIScreen.mainScreen().bounds

//private let kBoundsSize = kBounds.size

//let kWidth = kBoundsSize.width

//let kHeight = kBoundsSize.height

import UIKit

import AVFoundation // 二维码、条码扫码库

import Photos

/**

* 扫码控制器

*/

class ScanCodeController: UIViewController {

// 输入数据源

var input: AVCaptureDeviceInput!

// 数据输出源

var output: AVCaptureMetadataOutput!

// var output1D: AVCaptureMetadataOutput!

// var output2D: AVCaptureMetadataOutput!

// 输入输出中间桥梁,负责把捕获的音频视频数据输出到输出设备中

var session: AVCaptureSession!

// 相机拍摄预览图层

var layerView: AVCaptureVideoPreviewLayer!

// 预览图层尺寸

var layerViewSize: CGSize = CGSizeZero

// 有效扫码范围

// var recognitionFrame: CGRect = CGRect(x: 20, y: (20+44)/2+(kHeight-(kWidth-20-20))/2, width: kWidth-20-20, height: kWidth-20-20)

var recognitionFrame = CGRect(x: kWidth*0.1, y: 64/2+(kHeight-kWidth*0.8)/2, width: kWidth*0.8, height: kWidth*0.8)

// 扫码动画视图

var aniView: UIImageView!

// MARK: 初始化扫码器

func defaultInitScan() {

let device = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo)

do {

//let w = kWidth

//let h = kHeight-20-44

// let perH = w*0.8/h

// 输入源

try self.input = AVCaptureDeviceInput(device: device)

// 输出源

self.output = AVCaptureMetadataOutput()

self.output.setMetadataObjectsDelegate(self, queue: dispatch_get_main_queue())

// self.output.rectOfInterest = CGRectMake(0.1, (1-perH)/2, 0.8, perH);

// session设置

self.session = AVCaptureSession()

self.session.sessionPreset = AVCaptureSessionPresetHigh

self.session.addInput(self.input)

self.session.addOutput(self.output)

// 设置扫码的格式 注意这个地方有先后顺序

// self.output.metadataObjectTypes = self.output.availableMetadataObjectTypes

self.output.metadataObjectTypes = [

// 一维码

AVMetadataObjectTypeUPCECode, // 美国统一代码委员会制定,主要用于美国和加拿大地区

AVMetadataObjectTypeCode39Code,

AVMetadataObjectTypeCode39Mod43Code,

AVMetadataObjectTypeEAN13Code, // 通用商品条码

AVMetadataObjectTypeEAN8Code, // 通用商品条码

AVMetadataObjectTypeCode93Code,

AVMetadataObjectTypeCode128Code,

AVMetadataObjectTypeInterleaved2of5Code,

AVMetadataObjectTypeITF14Code,

AVMetadataObjectTypeAztecCode,

// 二维码

AVMetadataObjectTypePDF417Code,

AVMetadataObjectTypeDataMatrixCode,

AVMetadataObjectTypeQRCode,

]

// 扫码视图

self.layerView = AVCaptureVideoPreviewLayer(session: self.session)

self.layerView.videoGravity = AVLayerVideoGravityResizeAspectFill

self.layerView.frame = CGRectMake(0, 64, kWidth, kHeight-64)

self.layerViewSize = self.layerView.frame.size

self.view.layer.addSublayer(self.layerView)

// 开始扫码

self.session.startRunning()

do {

try device.lockForConfiguration()

// // 滤镜的设置吗?不是很确定

// let torchMode: AVCaptureTorchMode = device.torchMode

// device.torchMode = (torchMode == .Off) ? .On : .Off

// device.torchMode = .Off

// 放大焦距

// MARK: 通过设置焦距来解决条码扫码效率低的问题 看来问题还是没有解决

if device.activeFormat.videoMaxZoomFactor > 2 {

device.videoZoomFactor = 2

} else {

device.videoZoomFactor = device.activeFormat.videoMaxZoomFactor

}

device.unlockForConfiguration()

} catch {

print(error)

}

} catch {

print(error)

}

}

// 扫码框和动画

func drawRecognitionView() {

let borderWidth: CGFloat = 2

let recognitionView = UIView(frame: self.recognitionFrame)

self.view.addSubview(recognitionView)

recognitionView.backgroundColor = UIColor.clearColor()

recognitionView.layer.borderColor = UIColor.whiteColor().CGColor

recognitionView.layer.borderWidth = borderWidth

let color = UIColor(red: 0, green: 0, blue: 0, alpha: 0.5)

let colour = UIColor(red: 68.0/255.0, green: 164.0/255.0, blue: 252.0/255.0, alpha: 1)

let per: CGFloat = 0.1

let topView = UIView(frame: CGRect(x: 0, y: 0, width: kWidth, height: CGRectGetMinY(recognitionView.frame)))

self.view.addSubview(topView)

topView.backgroundColor = color

let leftView = UIView(frame: CGRect(x: 0, y: CGRectGetMinY(recognitionView.frame), width: CGRectGetMinX(recognitionView.frame), height: CGRectGetHeight(recognitionView.bounds)))

self.view.addSubview(leftView)

leftView.backgroundColor = color

let bottomView = UIView(frame: CGRect(x: 0, y: CGRectGetMaxY(recognitionView.frame), width: kWidth, height: kHeight-CGRectGetMaxY(recognitionView.frame)))

self.view.addSubview(bottomView)

bottomView.backgroundColor = color

let rightView = UIView(frame: CGRect(x: CGRectGetMaxX(recognitionView.frame), y: CGRectGetMinY(recognitionView.frame), width: kWidth-CGRectGetMaxX(recognitionView.frame), height: CGRectGetHeight(recognitionView.frame)))

self.view.addSubview(rightView)

rightView.backgroundColor = color

let topLeftView = UIView(frame: CGRect(x: CGRectGetMinX(recognitionView.frame)-10, y: CGRectGetMinY(recognitionView.frame)-10, width: CGRectGetWidth(recognitionView.bounds)*per, height: 10))

self.view.addSubview(topLeftView)

topLeftView.backgroundColor = colour

let topRightView = UIView(frame: CGRect(x: CGRectGetMaxX(recognitionView.frame)-CGRectGetWidth(recognitionView.bounds)*per+10, y: CGRectGetMinY(recognitionView.frame)-10, width: CGRectGetWidth(recognitionView.bounds)*per, height: 10))

self.view.addSubview(topRightView)

topRightView.backgroundColor = colour

let leftTopView = UIView(frame: CGRect(x: CGRectGetMinX(recognitionView.frame)-10, y: CGRectGetMinY(recognitionView.frame)-10, width: 10, height: CGRectGetWidth(recognitionView.bounds)*per))

self.view.addSubview(leftTopView)

leftTopView.backgroundColor = colour

let leftBottomView = UIView(frame: CGRect(x: CGRectGetMinX(recognitionView.frame)-10, y: CGRectGetMaxY(recognitionView.frame)-CGRectGetWidth(recognitionView.bounds)*per+10, width: 10, height: CGRectGetWidth(recognitionView.bounds)*per))

self.view.addSubview(leftBottomView)

leftBottomView.backgroundColor = colour

let bottomLeftView = UIView(frame: CGRect(x: CGRectGetMinX(recognitionView.frame)-10, y: CGRectGetMaxY(recognitionView.frame), width: CGRectGetWidth(recognitionView.bounds)*per, height: 10))

self.view.addSubview(bottomLeftView)

bottomLeftView.backgroundColor = colour

let bottomRightView = UIView(frame: CGRect(x: CGRectGetMaxX(recognitionView.frame)-CGRectGetWidth(recognitionView.bounds)*per+10, y: CGRectGetMaxY(recognitionView.frame), width: CGRectGetWidth(recognitionView.bounds)*per, height: 10))

self.view.addSubview(bottomRightView)

bottomRightView.backgroundColor = colour

let rightTopView = UIView(frame: CGRect(x: CGRectGetMaxX(recognitionView.frame), y: CGRectGetMinY(recognitionView.frame)-10, width: 10, height: CGRectGetWidth(recognitionView.bounds)*per))

self.view.addSubview(rightTopView)

rightTopView.backgroundColor = colour

let rightBottomView = UIView(frame: CGRect(x: CGRectGetMaxX(recognitionView.frame), y: CGRectGetMaxY(recognitionView.frame)-CGRectGetWidth(recognitionView.bounds)*per+10, width: 10, height: CGRectGetWidth(recognitionView.bounds)*per))

self.view.addSubview(rightBottomView)

rightBottomView.backgroundColor = colour

let im = UIImage(named: "smx_")!

let imw = CGFloat(CGImageGetWidth(im.CGImage))

let imh = CGFloat(CGImageGetHeight(im.CGImage))

let factw = CGRectGetWidth(recognitionView.bounds)

let facth = factw * imh / imw

self.aniView = UIImageView(frame: CGRect(x: CGRectGetMinX(recognitionView.frame), y: CGRectGetMinY(recognitionView.frame), width: factw, height: facth))

self.view.addSubview(self.aniView)

self.aniView.image = im

self.aniView.contentMode = .ScaleAspectFit

let beginPt = self.aniView.center

let endPt = CGPoint(x: beginPt.x, y: CGRectGetMaxY(recognitionView.frame)-CGRectGetHeight(self.aniView.bounds)/2)

UIView.animateWithDuration(3, delay: 0, options: [.CurveLinear, .Repeat, .Autoreverse], animations: {

[unowned self] in

self.aniView.center = endPt

}) { (finish) in

}

}

override func viewDidLoad() {

super.viewDidLoad()

// Do any additional setup after loading the view, typically from a nib.

self.navigationItem.title = "My Scan Code"

//let scannerBarButtonItem = UIBarButtonItem(image: UIImage(named: "sm_")!, style: .Plain, target: self, action: #selector(ScanCodeController.startScaning))

let libraryBarButtonItem = UIBarButtonItem(title: "相册", style: .Plain, target: self, action: #selector(ScanCodeController.scanLibrary))

//self.navigationItem.rightBarButtonItems = [libraryBarButtonItem, scannerBarButtonItem]

self.navigationItem.rightBarButtonItem = libraryBarButtonItem

self.defaultInitScan()

self.drawRecognitionView()

}

override func viewWillDisappear(animated: Bool) {

super.viewWillDisappear(animated)

if self.session.running {

self.session.stopRunning()

}

}

// MARK: 浏览相册,选择相册中的二维码图片

func scanLibrary() {

if !ScanCodeController.photoLibraryIsAvailable() {

return ;

}

let imagePickVC = UIImagePickerController()

imagePickVC.delegate = self

imagePickVC.sourceType = .SavedPhotosAlbum

self.presentViewController(imagePickVC, animated: true, completion: nil)

}

// 开始扫码

func startScaning() {

if !self.session.running {

self.session.startRunning()

}

}

override func didReceiveMemoryWarning() {

super.didReceiveMemoryWarning()

// Dispose of any resources that can be recreated.

}

}

extension ScanCodeController: AVCaptureMetadataOutputObjectsDelegate {

func captureOutput(captureOutput: AVCaptureOutput!, didOutputMetadataObjects metadataObjects: [AnyObject]!, fromConnection connection: AVCaptureConnection!) {

if metadataObjects.count > 0 {

// 停止扫码

// if self.session.running {

// self.session.stopRunning()

// }

// 结果对象

let metadataObject = metadataObjects.last as! AVMetadataMachineReadableCodeObject

// 显示结果

let alertVC = UIAlertController(title: nil, message: metadataObject.stringValue, preferredStyle: .Alert)

let action = UIAlertAction(title: "确定", style: .Cancel, handler: { [unowned alertVC](_) in

alertVC.dismissViewControllerAnimated(true, completion: nil)

})

alertVC.addAction(action)

self.presentViewController(alertVC, animated: true, completion: nil)

}

}

}

extension ScanCodeController: UIImagePickerControllerDelegate, UINavigationControllerDelegate {

func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {

var resultStr: String = ""

// 选择图片

let im = info[UIImagePickerControllerOriginalImage] as! UIImage

// 二维码识别

// CIDetectorTypeText CIDetectorTypeQRCode

let detectorQR = CIDetector(ofType: CIDetectorTypeQRCode, context: nil, options: [CIDetectorAccuracy : CIDetectorAccuracyHigh])

// 开始识别

let featuresQR = detectorQR.featuresInImage(CIImage(image: im)!)

let featureQR = featuresQR.last as? CIQRCodeFeature

if let feature = featureQR {

resultStr = "[QRCode] " + feature.messageString

}

// // 文本识别

// let detectorText = CIDetector(ofType: CIDetectorTypeText, context: nil, options: [CIDetectorAccuracy : CIDetectorAccuracyHigh])

//

// // 开始识别

// let featuresText = detectorText.featuresInImage(CIImage(image: im)!)

//

// let featureText = featuresText.last as? CITextFeature

//

// if let feature = featureText {

// if resultStr.isEmpty {

// resultStr += "\n"

// }

// resultStr += ("[Text] " + "")

// for fea in feature.subFeatures {

// print(fea)

// }

// }

picker.dismissViewControllerAnimated(true) {

[unowned self] in

var alertVC: UIAlertController? = nil

if !resultStr.isEmpty {

// 显示结果

alertVC = UIAlertController(title: nil, message: resultStr, preferredStyle: .Alert)

} else {

alertVC = UIAlertController(title: nil, message: "不能识别的图片", preferredStyle: .Alert)

}

let action = UIAlertAction(title: "确定", style: .Cancel, handler: { [weak alertVC](_) in

alertVC!.dismissViewControllerAnimated(true, completion: nil)

})

alertVC!.addAction(action)

self.presentViewController(alertVC!, animated: true, completion: nil)

}

self.startScaning()

}

func imagePickerControllerDidCancel(picker: UIImagePickerController) {

self.startScaning()

picker.dismissViewControllerAnimated(true, completion: nil)

}

}

extension ScanCodeController {

// MARK: 相机是否可用

class func cameraIsAvailable() -> Bool {

let status = AVCaptureDevice.authorizationStatusForMediaType(AVMediaTypeVideo)

if status == .Restricted || status == .Denied {

UIApplication.sharedApplication().openURL(NSURL(string: UIApplicationOpenSettingsURLString)!)

return false

} else {

return true

}

}

// MARK: 相册是否可用

class func photoLibraryIsAvailable() -> Bool {

let status = PHPhotoLibrary.authorizationStatus()

if status == .Restricted || status == .Denied {

UIApplication.sharedApplication().openURL(NSURL(string: UIApplicationOpenSettingsURLString)!)

return false

} else {

return true

}

}

}

你可能感兴趣的:(二维码识别)