swift版二维码扫描和生成


http://download.csdn.net/detail/koocui/9857846


类扩展

import UIKit


extension UIViewController{

    func showAlert(title:String,message:String,handler:@escaping((UIAlertAction)->Void)){

        let alert:UIAlertController =UIAlertController(title: title, message: message, preferredStyle: .alert)

        let action:UIAlertAction =UIAlertAction(title: "确定", style: .default, handler: handler)

        alert.addAction(action)

        self.present(alert, animated:true, completion: nil)

    }

}



一,二维码扫描;


1,扫描页面上面的View

//

//  MaskView.swift

//  二维码

//

//  Created by CJW on 17/5/26.

//  Copyright © 2017 cjw. All rights reserved.

//


import UIKit


class MaskView: UIView {


    var lineLayer:CALayer? =nil

    // Only override draw() if you perform custom drawing.

    // An empty implementation adversely affects performance during animation.

    overridefunc draw(_ rect:CGRect) {

        let width:CGFloat = rect.size.width

        let height:CGFloat = rect.size.height

        let pickingFieldWIdth:CGFloat =300

        let pickingFieldHeight:CGFloat =300

        let contextRef =UIGraphicsGetCurrentContext()

        contextRef!.saveGState()

        //蒙版

        contextRef?.setFillColor(red:0, green: 0, blue:0, alpha: 0.35)

        contextRef?.setLineWidth(3)

        let pickingFIeldRect =CGRect(x: (width - pickingFieldWIdth) /2, y: (height - pickingFieldHeight) /2, width: pickingFieldWIdth, height: pickingFieldHeight)

        let pickingFieldPath =UIBezierPath(rect: pickingFIeldRect)

        let bezierPathRect =UIBezierPath(rect: rect)

        //填充使用奇偶法则

        bezierPathRect.usesEvenOddFillRule =true

        bezierPathRect.fill()

        contextRef?.setLineWidth(2)

        //框框

        contextRef?.setStrokeColor(red:27/255.0, green:181/255.0, blue:254/255.0, alpha:1)

        pickingFieldPath.stroke()

        contextRef?.restoreGState()

        self.layer.contentsGravity =kCAGravityCenter

        

    }


    overridefunc awakeFromNib() {

        super.awakeFromNib()

        self.backgroundColor =UIColor.black.withAlphaComponent(0.4)

        self.lineLayer =CALayer(layer: layer)

        self.lineLayer?.contents =UIImage(named: "line")?.cgImage

        self.layer.addSublayer(self.lineLayer!)

        self.resumeAnimation()

        

        NotificationCenter.default.addObserver(self, selector: #selector(resumeAnimation), name:NSNotification.Name.UIApplicationDidBecomeActive, object: nil)

        

        NotificationCenter.default.addObserver(self, selector: #selector(stopAnimation), name:NSNotification.Name.UIApplicationDidEnterBackground, object: nil)

        

    }

    

    overridefunc layoutSubviews() {

        super.layoutSubviews()

        self.setNeedsDisplay()

        self.lineLayer?.frame =CGRect(x: (self.frame.size.width - 300) / 2, y: (self.frame.size.height - 300) / 2, width:300, height: 2)

    }

    func stopAnimation(){

        self.lineLayer?.removeAnimation(forKey:"translationY")

    }

    

    func resumeAnimation(){

        let basic =CABasicAnimation(keyPath:"transform.translation.y")

        basic.fromValue = (0)

        basic.toValue = (300)

        basic.duration =1.5

        basic.repeatCount =Float(NSIntegerMax)

        self.lineLayer?.add(basic, forKey:"translationY")

    }


}


2,扫描二维码的VC


//

//  ScanViewController.swift

//  二维码

//

//  Created by CJW on 17/5/26.

//  Copyright © 2017 cjw. All rights reserved.

//  扫描二维码


import UIKit

import AVFoundation


class ScanViewController:UIViewController,AVCaptureMetadataOutputObjectsDelegate {


    var flashOpen:Bool? =nil

    privatelazy var session:AVCaptureSession = {

        //获取摄像设备

        let device:AVCaptureDevice =AVCaptureDevice.defaultDevice(withMediaType:AVMediaTypeVideo)

        //创建输入流

        var input:AVCaptureDeviceInput?

        do {

            let myinput:AVCaptureDeviceInput=tryAVCaptureDeviceInput(device: device)

            input = myinput

        }catchlet error asNSError{

            print(error)

        }

        //创建输出流

        let output:AVCaptureMetadataOutput =AVCaptureMetadataOutput()

        

        output.setMetadataObjectsDelegate(self, queue:DispatchQueue.main)

        //设置扫描区域的比例

        let width =300 / self.view.bounds.height

        let height =300 / self.view.bounds.width

        output.rectOfInterest =CGRect(x: (1-width)/2, y: (1-height) / 2, width: width, height: height)

        let session1 =AVCaptureSession()

        //高质量采集率

        session1.canSetSessionPreset(AVCaptureSessionPresetHigh)

        session1.addInput(input)

        session1.addOutput(output)

        

        //设置扫码支持的编码格式(这里设置条形码和二维码兼容)

        output.metadataObjectTypes = [AVMetadataObjectTypeQRCode,AVMetadataObjectTypeEAN13Code,AVMetadataObjectTypeEAN8Code,AVMetadataObjectTypeCode128Code]

        return session1

    

    }()

    

    overridefunc viewDidLoad() {

        super.viewDidLoad()


        self.navigationItem.rightBarButtonItem =UIBarButtonItem(title: "打开闪光灯", style: .plain, target:self, action: #selector(rightBarButtonDidClick))

        let layer:AVCaptureVideoPreviewLayer =AVCaptureVideoPreviewLayer(session:session)

        layer.videoGravity =AVLayerVideoGravityResizeAspectFill

        layer.frame =self.view.layer.bounds

        self.view.layer.insertSublayer(layer, at: 0)

        

        

    }


    overridefunc viewWillAppear(_ animated:Bool) {

        super.viewWillAppear(animated)

        self.session.startRunning()

    }

    overridefunc viewWillDisappear(_ animated:Bool) {

        super.viewWillDisappear(animated)

        self.session.stopRunning()

    }

    overridefunc didReceiveMemoryWarning() {

        super.didReceiveMemoryWarning()

        // Dispose of any resources that can be recreated.

    }

    //MARK: - AVCaptureMetadataOutputObjectsDelegate

    func captureOutput(_ captureOutput:AVCaptureOutput!, didOutputMetadataObjects metadataObjects: [Any]!, from connection:AVCaptureConnection!) {

        if metadataObjects.count >0 {

            self.session.stopRunning()

            let metadataObject:AVMetadataMachineReadableCodeObject = metadataObjects.firstas! AVMetadataMachineReadableCodeObject

            self.showAlert(title:"扫面结果", message: metadataObject.stringValue, handler: { (ht) in

                self.session.startRunning()

            })

        }

    }

    


}

//打开闪光灯

extension ScanViewController {

    func rightBarButtonDidClick(btn:UIBarButtonItem){

        self.flashOpen =!self.flashOpen!

        let device:AVCaptureDevice =AVCaptureDevice.defaultDevice(withMediaType:AVMediaTypeAudio)

        if device.hasTorch&& device.hasFlash {

            ifself.flashOpen! {

            self.navigationItem.rightBarButtonItem =UIBarButtonItem(title: "关闭闪光灯", style: .plain, target:self, action: #selector(rightBarButtonDidClick))

            }

            device.torchMode =AVCaptureTorchMode.on

            device.flashMode =AVCaptureFlashMode.on

        }else {

             self.navigationItem.rightBarButtonItem =UIBarButtonItem(title: "打开闪光灯", style: .plain, target:self, action: #selector(rightBarButtonDidClick))

            device.torchMode =AVCaptureTorchMode.off

              device.flashMode =AVCaptureFlashMode.off

        }

    

    }

    

}




二,识别图片二维码;


//

//  ImageViewController.swift

//  二维码

//

//  Created by CJW on 17/5/26.

//  Copyright © 2017 cjw. All rights reserved.

//  长按识别二维码


import UIKit


class ImageViewController:UIViewController,UINavigationControllerDelegate,UIImagePickerControllerDelegate{


    @IBOutletweak var imageView:UIImageView!

    overridefunc viewDidLoad() {

        super.viewDidLoad()


        self.navigationItem.rightBarButtonItem =UIBarButtonItem(title: "从相册获取", style:UIBarButtonItemStyle.plain, target:self, action: #selector(rightBarBtnItemClick(item:)))

    }


    overridefunc didReceiveMemoryWarning() {

        super.didReceiveMemoryWarning()

        // Dispose of any resources that can be recreated.

    }

    //MARK:- 从相册选择

    func rightBarBtnItemClick(item:UIBarButtonItem){

        ifUIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.photoLibrary) {

            let controller =UIImagePickerController()

            controller.sourceType =UIImagePickerControllerSourceType.photoLibrary

            controller.delegate =self

            self.present(controller, animated:true, completion: { 

                

            })

        }else {

            self.showAlert(title:"提示", message:"设备不支持访问相册", handler: { (text)in

            })

        }

    }

    //MARK:- UIImagePickerControllerDeleGate

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

        picker.dismiss(animated:true) { 

            let image = info[UIImagePickerControllerOriginalImage]

            self.imageView.image = imageas! UIImage?

            

        }

    }


    //MARK:- 长按识别二维码

    

    @IBActionfunc handleLongPress(_ sender:UILongPressGestureRecognizer) {

        if sender.state ==UIGestureRecognizerState.began {

            self.findQRCodeFromImage(image:self.imageView.image!)

        }

    }

    //

    func  findQRCodeFromImage(image:UIImage){

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

        let faetures = detector.features(in:CIImage(cgImage: image.cgImage!))

        if faetures.count >=1 {

            let feature:CIQRCodeFeature = faetures.firstas! CIQRCodeFeature

            self.showAlert(title:"扫描结果", message: feature.messageString!, handler: { (alert) in

                

            })

        }else {

            self.showAlert(title:"提示", message:"图片里没有二维码", handler: { (alert)in

                

            })

        }

    }

}


三,识别图片二维码;


//

//  CreateViewController.swift

//  二维码

//

//  Created by CJW on 17/5/26.

//  Copyright © 2017 cjw. All rights reserved.

//  生成二维码


import UIKit

import CoreFoundation


private let kRandomColor =UIColor.creatColor(r:CGFloat(arc4random_uniform(255)), g:CGFloat(arc4random_uniform(255)), b:CGFloat(arc4random_uniform(255)))

private let qrImageSize =CGSize(width: 300, height:300)


class CreateViewController:UIViewController,UITextFieldDelegate {


    @IBOutletweak var textFiled:UITextField!

    

    @IBOutletweak var imageView:UIImageView!

    

    overridefunc viewDidLoad() {

        super.viewDidLoad()

      self.imageView.image = self.createQRImageWithString("小崔哥", andSize: qrImageSize)


    }

    func textFieldShouldReturn(_ textField:UITextField) -> Bool {

        self.createButtonDidClick(UIButton())

        returntrue

    }

    //MARK:- methods

    

    @IBActionfunc createButtonDidClick(_ sender:UIButton) {

        self.textFiled.resignFirstResponder()

        if (self.textFiled.text?.characters.count)! > 0 {

            self.imageView.image =self.createQRImageWithString(self.textFiled.text!, andSize: qrImageSize)

        }else {

            self.showAlert(title:"提示", message:"请先输入文字", handler: { (alter)in

                

            })

        }

    }

      //为二维码改变颜色

    @IBActionfunc changeColorButtonDidClick(_ sender:UIButton) {

        let image =self.createQRImageWithString(self.textFiled.text!, andSize: qrImageSize)

        self.imageView.image =self.changeColorForQRImage(iamge: image, backColor:kRandomColor, frontColor:kRandomColor)

        

    }

    

    

    @IBActionfunc addSamllImageButtonDidClick(_ sender:UIButton) {

       self.imageView.image =self.addSmallImageForQRImage(qrImage:self.imageView.image!)

    }

    

    func createQRImageWithString(_ stirng:String,andSize size:CGSize)->UIImage{

        let stringData:Data = stirng.data(using:String.Encoding(rawValue:String.Encoding.utf8.rawValue))!

        let qrFileter =CIFilter(name: "CIQRCodeGenerator")

        qrFileter?.setValue(stringData, forKey:"inputMessage")

        qrFileter?.setValue("M", forKey:"inputCorrectionLevel")

        

        let qrImage = qrFileter?.outputImage

        //放大并绘制二维码(上面生成的二维码很小需要放大)

        let cgImage =CIContext(options: nil).createCGImage(qrImage!, from: (qrImage?.extent)!)

    

        UIGraphicsBeginImageContext(size)

        let context =UIGraphicsGetCurrentContext()

        context!.interpolationQuality = .none

        

        //反转一下图片,不然生产的QRCode就是上下颠倒的

        context!.scaleBy(x:1.0, y: -1.0);


        context?.draw(cgImage!, in: context!.boundingBoxOfClipPath)

        

        let condeImage:UIImage =UIGraphicsGetImageFromCurrentImageContext()!

        UIGraphicsEndImageContext()

        

        

        return condeImage

        

        

    }


    //改变二维码颜色

    func changeColorForQRImage(iamge:UIImage,backColor:UIColor,frontColor:UIColor)->UIImage{

         let colorFilter =CIFilter(name: "CIFalseColor", withInputParameters: ["inputImage":CIImage.init(cgImage:iamge.cgImage!),"inputColor0":CIColor(cgColor: frontColor.cgColor),"inputColor1":CIColor(cgColor: backColor.cgColor)])

        returnUIImage(ciImage: (colorFilter?.outputImage)!)

    }

  

    //在二维码中心加个小图

    func  addSmallImageForQRImage(qrImage:UIImage) ->UIImage {

        UIGraphicsBeginImageContext(qrImage.size)

        qrImage.draw(in:CGRect(x: 0, y:0, width: qrImage.size.width, height: qrImage.size.height))

        let iamge =UIImage(named: "small")

        let iamgeW:CGFloat =50

        let iamgeX = (qrImage.size.width - iamgeW)*0.5

        let iamgeY = (qrImage.size.height - iamgeW)*0.5

        iamge?.draw(in:CGRect(x: iamgeX, y: iamgeY, width: iamgeW, height: iamgeW))

        let result =UIGraphicsGetImageFromCurrentImageContext()

        UIGraphicsEndImageContext()

        return result!

    }


    

    overridefunc didReceiveMemoryWarning() {

        super.didReceiveMemoryWarning()

        // Dispose of any resources that can be recreated.

    }

    overridefunc touchesBegan(_ touches:Set<UITouch>, with event:UIEvent?) {

//        self.textFiled.becomeFirstResponder()

        self.view.endEditing(true)

    }

    


}

extension UIColor{

    classfunc creatColor(r:CGFloat, g:CGFloat, b:CGFloat)->UIColor {

      returnUIColor(red: (r)/255.0 , green: (g)/255.0 , blue: (b)/255.0 , alpha: 1.0)

    }

}



demo下载地址为:http://download.csdn.net/detail/koocui/9857846















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