二维码扫描与生成

ViewController

import UIKit
import AVFoundation
class ViewController: UIViewController {
    let captureSession = AVCaptureSession()
    var readerRect = CGRect.zero
    let line = UIImageView()
    var uping = true
    var timer: NSTimer?
    let kWidth = UIScreen.mainScreen().bounds.size.width
    let kHeight = UIScreen.mainScreen().bounds.size.height

    override func viewDidLoad() {
        super.viewDidLoad()        
        title = "二维码扫描"
        navigationItem.leftBarButtonItem = UIBarButtonItem(title: "选取图片", style: .Done, target: self, action: #selector(presentImgPicker))
        navigationItem.rightBarButtonItem = UIBarButtonItem(title: "生成二维码", style: .Done, target: self, action: #selector(pushToGenerator))

        let status = AVCaptureDevice.authorizationStatusForMediaType(AVMediaTypeVideo)
        switch status {
        case .NotDetermined://用户未决定
            AVCaptureDevice.requestAccessForMediaType(AVMediaTypeVideo, completionHandler: {
                return $0 == true ? self.initialization() : self.showAlert()
            })
        case .Authorized://已允许权限
            initialization()
        case .Restricted: break//权限受限
        case .Denied://拒绝权限
            showAlert()
        }
    }

    override func viewWillAppear(animated: Bool) {
        super.viewWillAppear(animated)
        if !captureSession.running {
            captureSession.startRunning()
        }
        fireTimer()
    }

    override func viewDidDisappear(animated: Bool) {
        super.viewDidDisappear(animated)
        captureSession.stopRunning()
        if (timer != nil) {
            timer!.invalidate()
            timer = nil
        }
    }

    func presentImgPicker() {
        let imgPicker = UIImagePickerController()
        imgPicker.sourceType = .PhotoLibrary
        imgPicker.delegate = self
        presentViewController(imgPicker, animated: true, completion: nil)
    }

    func pushToGenerator() {
        let genVC = GeneratorVC(nibName: "GeneratorVC", bundle: nil)
        navigationController?.pushViewController(genVC, animated: true)
    }

    func initialization() {
        initScanRect()
        setupSession()
        setupScanLine()
        makeShawdowView()
        fireTimer()
    }

    func showAlert() {
        let alert = UIAlertController(title: "提示", message: "请前往\"设置->隐私->相机->二维码\"打开相机权限", preferredStyle: .Alert)
        let action = UIAlertAction(title: "确定", style: .Cancel, handler: nil)
        alert.addAction(action)
        presentViewController(alert, animated: true, completion: nil)
    }

    func initScanRect() {
        let scanWidth = kWidth * 2 / 3
        readerRect = CGRect(x: (kWidth - scanWidth) / 2, y: (kHeight - scanWidth) / 2 * 0.8, width: scanWidth, height: scanWidth)
    }

    func setupSession() {
        let captureDevice = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo)
        let input: AVCaptureDeviceInput?
        do {
            input = try AVCaptureDeviceInput(device: captureDevice)
        } catch _ {
            fatalError("Could not create capture device input.")
        }
        captureSession.addInput(input)

        let output = AVCaptureMetadataOutput()
        captureSession.addOutput(output)
        output.setMetadataObjectsDelegate(self, queue: dispatch_get_main_queue())
        output.metadataObjectTypes = [AVMetadataObjectTypeQRCode,
                                      AVMetadataObjectTypeCode93Code,
                                      AVMetadataObjectTypeCode39Code,
                                      AVMetadataObjectTypeCode128Code]

        let layer = AVCaptureVideoPreviewLayer.init(session: captureSession)
        layer.videoGravity = AVLayerVideoGravityResizeAspectFill
        layer.frame = view.bounds
        view.layer .insertSublayer(layer, atIndex: 0)

        let x = readerRect.origin.x / kWidth
        let y = readerRect.origin.y / kHeight
        let width = readerRect.size.width / kWidth
        let height = readerRect.size.height / kHeight
        output.rectOfInterest = CGRect(x: x, y: y, width: width, height: height)
        captureSession.startRunning()
    }

    func setupScanLine() {
        let imgWidth: CGFloat = 20.0
        let imgX: CGFloat = readerRect.origin.x
        let imgY: CGFloat = readerRect.origin.y
        let width = CGFloat(readerRect.size.width)
        let height = CGFloat(readerRect.size.height)
        let cornerTL = CGRect(x: imgX, y: imgY, width: imgWidth, height: imgWidth)
        let cornerTR = CGRect(x: imgX + width - imgWidth, y: imgY, width: imgWidth, height: imgWidth)
        let cornerBL = CGRect(x: imgX, y: imgY+height-imgWidth, width: imgWidth, height: imgWidth)
        let cornerBR = CGRect(x: imgX + width - imgWidth, y: imgY+height-imgWidth, width: imgWidth, height: imgWidth)
        let frames = [cornerTL, cornerTR, cornerBL, cornerBR]
        for (index, frame) in frames.enumerate() {
            let imgView = UIImageView(frame: frame)
            imgView.image = UIImage(named: "ScanQR\(index + 1)")
            view.addSubview(imgView)
        }

        let lineRect = CGRect(x: imgX, y: imgY, width: width, height: width / 640 * 24)
        line.frame = lineRect
        line.image = UIImage(named: "ScanLine")
        view.addSubview(line)

        let label = UILabel(frame: CGRect(x: 0, y: imgY + height + 20, width: kWidth, height: 20))
        label.textAlignment = .Center
        label.font = UIFont.systemFontOfSize(12)
        label.textColor = UIColor.whiteColor()
        label.text = "请将二维码放入框内,即可自动扫描!"
        view.addSubview(label)
    }

    func makeShawdowView() {
        UIGraphicsBeginImageContext(view.bounds.size)
        let context = UIGraphicsGetCurrentContext()
        UIColor(white: 0, alpha: 0.55).setFill()
        CGContextFillRect(context, view.bounds)

        UIColor.whiteColor().setStroke()
        CGContextStrokeRectWithWidth(context, readerRect, 1)
        CGContextClearRect(context, readerRect)

        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()

        let shadowBgview = UIImageView(frame: view.bounds)
        shadowBgview.image = image
        view.addSubview(shadowBgview)
    }

    func fireTimer() {
        timer = NSTimer.scheduledTimerWithTimeInterval(0.02, target: self, selector: #selector(beginAnimation), userInfo: nil, repeats: true)
    }

    func beginAnimation() {
        var frame  = line.frame
        if uping {
            if CGRectGetMinY(frame) > CGRectGetMinY(readerRect) {
                frame.origin.y -= 2
                line.frame = frame
                return;
            }
            uping = false
        } else {
            if CGRectGetMaxY(frame) < CGRectGetMaxY(readerRect) {
                frame.origin.y += 2
                line.frame = frame
                return;
            }
            uping = true
        }
    }
}

extension ViewController: AVCaptureMetadataOutputObjectsDelegate {
    func captureOutput(captureOutput: AVCaptureOutput!, didOutputMetadataObjects metadataObjects: [AnyObject]!, fromConnection connection: AVCaptureConnection!) {
        if metadataObjects.count > 0 {
            captureSession.stopRunning()
            timer!.invalidate()
            timer = nil
            let obj = metadataObjects.first as! AVMetadataMachineReadableCodeObject
            let resultVC = ResultViewController()
            resultVC.result = obj.stringValue
            navigationController?.pushViewController(resultVC, animated: true)
        }
    }
}

extension ViewController: UIImagePickerControllerDelegate, UINavigationControllerDelegate {
    func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {
        let detector = CIDetector(ofType: CIDetectorTypeQRCode, context: nil, options: [CIDetectorAccuracy:CIDetectorAccuracyHigh])
        let img = info[UIImagePickerControllerOriginalImage] as! UIImage
        let image = CIImage.init(image: img)
        let features = detector.featuresInImage(image!)
        picker.dismissViewControllerAnimated(true) {
            if features.count > 0 {
                let resultVC =  ResultViewController()
                let feature: CIQRCodeFeature = features[0] as! CIQRCodeFeature
                resultVC.result = feature.messageString
                self.navigationController?.pushViewController(resultVC, animated: true)
            }
        }
        for feature in features {
            let fea = feature as! CIQRCodeFeature
            print(fea.messageString)
        }
    }

    func imagePickerControllerDidCancel(picker: UIImagePickerController) {
        picker.dismissViewControllerAnimated(true, completion: nil)
    }
}

GeneratorVC

import UIKit
import AVFoundation
class GeneratorVC: UIViewController, UIGestureRecognizerDelegate {
    @IBOutlet weak var inputField: UITextField!
    @IBOutlet weak var imageView: UIImageView!
    @IBOutlet weak var infoLabel: UILabel!
    var selImage: UIImage?
    var showImage: UIImage?

    override func viewDidLoad() {
        super.viewDidLoad()
        imageView.hidden = true
        imageView.userInteractionEnabled = true
        infoLabel.hidden = true
        let longGesture = UILongPressGestureRecognizer(target: self, action: #selector(saveQRCode))
        longGesture.delegate = self;
        imageView.addGestureRecognizer(longGesture)

        let status = AVCaptureDevice.authorizationStatusForMediaType(AVMediaTypeVideo)
        switch status {
        case .NotDetermined://用户未决定
            AVCaptureDevice.requestAccessForMediaType(AVMediaTypeVideo, completionHandler: {
                if !$0 {
                    self.showAlert()
                }
            })
        case .Authorized: break//已允许权限
        case .Restricted: break//权限受限
        case .Denied://拒绝权限
            showAlert()
        }
    }

    func saveQRCode() {
        let alert = UIAlertController(title: "", message: "是否保存到本地相册", preferredStyle: .Alert)
        let action1 = UIAlertAction(title: "取消", style: .Cancel, handler: nil)
        let action2 = UIAlertAction(title: "确定", style: .Default) { (action) in
            UIImageWriteToSavedPhotosAlbum(self.showImage!, nil, nil, nil)
        }
        alert.addAction(action1)
        alert.addAction(action2)
        presentViewController(alert, animated: true, completion: nil)
    }

    func showAlert() {
        let alert = UIAlertController(title: "提示", message: "请前往\"设置->隐私->相机->二维码\"打开相机权限", preferredStyle: .Alert)
        let action = UIAlertAction(title: "确定", style: .Cancel, handler: nil)
        alert.addAction(action)
        presentViewController(alert, animated: true, completion: nil)
    }

    func generatorCode() {
        view.endEditing(true)
        var info = inputField.text
        if (info == "") {
            info = "http://www.jianshu.com/users/46342fd00794/latest_articles"
        }
        let data = info?.dataUsingEncoding(NSUTF8StringEncoding)
        let filter = CIFilter(name: "CIQRCodeGenerator")
        filter?.setValue(data, forKey: "inputMessage")
        filter?.setValue("H", forKey: "inputCorrectionLevel")
        let outputImage = filter?.outputImage
        let transform = CGAffineTransformMakeScale(5, 5)
        let transformImage = outputImage?.imageByApplyingTransform(transform)
        let context = CIContext(options: nil)
        let imageRef = context.createCGImage(transformImage!, fromRect: (transformImage?.extent)!)
        let qrImage = UIImage(CGImage: imageRef)
        let size = qrImage.size
        UIGraphicsBeginImageContext(size)
        qrImage.drawInRect(CGRect(x: 0, y: 0, width: size.width, height: size.height))
        let width = size.width * 0.3
        if selImage != nil {
            selImage?.drawInRect(CGRect(x: (size.width - width)/2, y: (size.width - width)/2, width: width, height: width))
        }
        showImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        imageView.image = showImage
        imageView.hidden = false
        infoLabel.hidden = false
    }

    @IBAction func pickImage(sender: AnyObject) {
        let imgPicker = UIImagePickerController()
        imgPicker.sourceType = .PhotoLibrary
        imgPicker.delegate = self
        presentViewController(imgPicker, animated: true, completion: nil)
    }    
}

extension GeneratorVC: UIImagePickerControllerDelegate, UINavigationControllerDelegate {
    func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {
        selImage = info[UIImagePickerControllerOriginalImage] as? UIImage
        generatorCode()
        picker.dismissViewControllerAnimated(true, completion: nil)
    }

    func imagePickerControllerDidCancel(picker: UIImagePickerController) {
        picker.dismissViewControllerAnimated(true, completion: nil)
    }
}

ResultViewController

import UIKit
class ResultViewController: UIViewController {
    internal var result = ""
    let kWidth = UIScreen.mainScreen().bounds.size.width
    let kHeight = UIScreen.mainScreen().bounds.size.height

    override func viewDidLoad() {
        super.viewDidLoad()       
        view.backgroundColor = UIColor.whiteColor()
        if !result.isEmpty {
            let httpAddresses = getUrlAddress(result)
            if httpAddresses.count > 0 {
                let http = httpAddresses.first!
                print(http)
                let webView = UIWebView(frame: CGRect(x: 0, y: 0, width: kWidth, height: kHeight))
                view.addSubview(webView)
                let request = NSURLRequest(URL: NSURL(string: http)!)
                webView.loadRequest(request)
            } else {
                for index in 0...1 {
                    let label = UILabel(frame: CGRect(x: 0, y: 164 + 80 * index, width: Int(kWidth), height: 50))
                    label.textColor = UIColor.blueColor()
                    label.font = UIFont.systemFontOfSize(25)
                    label.adjustsFontSizeToFitWidth = true
                    if index == 0 {
                        label.text = "  您的二维码信息如下:"
                    } else {
                        label.text = result
                        label.textAlignment = .Center
                    }
                    view.addSubview(label)
                }
            }
        }
    }

    func getUrlAddress(text: String) -> [String] {
        let pattern = "http?://([-\\w\\.]+)+(:\\d+)?(/([\\w/_\\.]*(\\?\\S+)?)?)?"
        var matches = [String]()
        do {
            let regex = try NSRegularExpression(pattern: pattern, options: NSRegularExpressionOptions(rawValue: 0))
            let nsstr = text as NSString
            let all = NSRange(location: 0, length: nsstr.length)
            regex.enumerateMatchesInString(text, options: NSMatchingOptions.init(rawValue: 0), range: all, usingBlock: { (result, flags, _) in
                matches.append(nsstr.substringWithRange(result!.range))
            })
        } catch {
            return [String]()
        }
        return matches
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值