Swift(十一):QRScanner 二维码生成、识别、扫描

2016-08-11  本文已影响297人  IMSong

一 、生成二维码

小诗一首
//
//  showQRController.swift
//  QRCode
//
//  Created by HMC on 16/8/11.
//  Copyright © 2016年 SKing. All rights reserved.
//

import UIKit
import CoreImage

class showQRController: UIViewController {
    
    @IBOutlet weak var QRImageView: UIImageView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        QRImageView.image = createQR("香雨如酥贵如珠,万家未觉身却无。 一心只为他人事,浓绿艳妆为谁梳?", iconImageName: "123")

        
    }
}

extension showQRController {
    
    func createQR(string : String?,iconImageName: String?) -> UIImage? {
        
        //创建二维码滤镜 固定格式 参数必须为 : CIQRCodeGenerator
        let filter = CIFilter(name: "CIQRCodeGenerator")
        
        //复位滤镜,以便下次使用
        filter?.setDefaults()
        
        //KVC 设置输入值  ps:key 固定为inputMessage ,value 必须为 nsdata 类型
        guard string != nil else {
            return nil
        }
        let inputData = string!.dataUsingEncoding(NSUTF8StringEncoding)
        filter?.setValue(inputData, forKey: "inputMessage")
        
        //设置纠错率 一般设置为M
        filter?.setValue("M", forKey: "inputCorrectionLevel")
        
        //接收滤镜返回的图片,由于太小 需要拉伸放大
        guard let image = filter?.outputImage else {
            
            return nil
        }
        //颜色滤镜
        let colorFilter = CIFilter(name: "CIFalseColor")
        colorFilter?.setDefaults()
        colorFilter?.setValue(image, forKey: "inputImage")
        //前景色
        colorFilter?.setValue(CIColor(red: 225/255.0, green: 77/255.0,blue: 0), forKey: "inputColor0")
        //背景色
        colorFilter?.setValue(CIColor(red: 1, green: 1,blue: 1), forKey: "inputColor1")
        
        guard let colorImage = colorFilter?.outputImage else{
            return nil
        }
        //放大25倍 重绘
        let matrix = CGAffineTransformMakeScale(25, 25)
        //将 CIImage 转换为 UIImage
        let QRImage = UIImage(CIImage:colorImage.imageByApplyingTransform(matrix))
        
        //判定 icon 是否为空
        guard iconImageName != nil else {
        
            return nil
        }
        
        //重新绘制中心小图
        if let iconImage = UIImage(named: iconImageName!)  {
            
            let rect = CGRectMake(0, 0, QRImage.size.width, QRImage.size.height)
            UIGraphicsBeginImageContext(rect.size)
            QRImage.drawInRect(rect)
            
            
            let iconSize = CGSizeMake(rect.size.width * 0.25, rect.size.height * 0.25)
            let x = (rect.width - iconSize.width ) * 0.5
            let y = (rect.height - iconSize.height ) * 0.5
            
            iconImage.drawInRect(CGRectMake(x,y,iconSize.width,iconSize.height))
            let resultImage = UIGraphicsGetImageFromCurrentImageContext()
            
            UIGraphicsEndImageContext()
            
            return resultImage
        }
        
        
     return QRImage
    }
    
    
}

二 、识别二维码

识别结果
//
//  detectorViewController.swift
//  QRCode
//
//  Created by HMC on 16/8/12.
//  Copyright © 2016年 SKing. All rights reserved.
//

import UIKit

class detectorViewController: UIViewController {
    
    
    @IBOutlet weak var imageView: UIImageView!
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // 获得 image
        guard let image = imageView.image else{
            
            return
        }
        //转换为 CIImage
        let ciImage = CIImage(image: image)
        
        //创建探测器
        let detector = CIDetector(ofType: CIDetectorTypeQRCode, context: nil, options: [CIDetectorAccuracy : CIDetectorAccuracyHigh])
        
        //返回结果
        let features = detector.featuresInImage(ciImage!)
        //遍历结果
        for feature in features {
            let qrcode = feature as! CIQRCodeFeature
            
            print(qrcode.messageString)
            
            //alert 显示识别出的内容
            let alert = UIAlertController(title: "识别内容", message:qrcode.messageString, preferredStyle: .Alert)
            let action = UIAlertAction(title: "关闭", style: .Default, handler: { (action : UIAlertAction) in
                self.dismissViewControllerAnimated(true, completion: nil)
            })
            
            alert.addAction(action)
            presentViewController(alert, animated: true, completion: nil)
            
            
        }
        
    }
}

三 、扫描二维码

扫描前 扫描后
//
//  scanQRViewController.swift
//  QRCode
//
//  Created by HMC on 16/8/15.
//  Copyright © 2016年 SKing. All rights reserved.
//

import UIKit
import AVFoundation

class scanQRViewController: UIViewController {
    
    lazy var session = AVCaptureSession()
    
    /// 扫描网格 距离 框的底部的长度
    @IBOutlet weak var lineToBottom: NSLayoutConstraint!
    /// 扫描框和扫描线的背景 View
    @IBOutlet weak var scanBackground: UIView!
    //扫描框
    @IBOutlet weak var scanDeadLine: UIImageView!
    
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // Do any additional setup after loading the view.
        startScan()
    }
    override func viewDidAppear(animated: Bool) {
        
        super.viewDidAppear(animated)
        
        startAnimationOfLine()
        
    }
    
}


// MARK: - 有关的 UI 和动画
extension scanQRViewController{
    /**
     开始扫描
     */
    func startScan(){
        //获取摄像头
        let hardWareDevice = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo)
        
        //输入
        guard let input = try? AVCaptureDeviceInput(device: hardWareDevice) else{
            return
        }
        
        //输出
        let output = AVCaptureMetadataOutput()
        //设置输出的代理
        output.setMetadataObjectsDelegate(self, queue: dispatch_get_main_queue())
        
        //连接输入输出
        //session = AVCaptureSession()
        guard session.canAddInput(input) else{
            
            return
        }
        guard session.canAddOutput(output) else {
            
            return
        }
        session.addInput(input)
        session.addOutput(output)
        //输出的二维码识别的码制(所有的码)
        output.metadataObjectTypes = output.availableMetadataObjectTypes
        
        
        //设置扫描的区域 0.0-1.0
//        let screenBounds = UIScreen.mainScreen().bounds
//        let x :CGFloat = scanBackground.frame.origin.x / screenBounds.size.width
//        let y :CGFloat = scanBackground.frame.origin.y / screenBounds.size.height
//        let width :CGFloat = scanBackground.frame.size.width / screenBounds.size.width
//        let height :CGFloat = scanBackground.frame.size.height / screenBounds.size.height
//        output.rectOfInterest = CGRectMake(y, x, height, width)
        
        //添加摄像头图层 (其实不是必须的)
        let captureLayer = AVCaptureVideoPreviewLayer(session: session)
        captureLayer.frame = view.layer.bounds
        view.layer.insertSublayer(captureLayer, atIndex: 0)
        
        // 启动回话: 此时开始采集数据,输出对象
        session.startRunning()
        
        
    }
    
    /**
     动画的设置
     */
    func startAnimationOfLine() {
        
        //初始化线的位置
        lineToBottom.constant = scanBackground.frame.height
        loadViewIfNeeded()
        
        //设置结束位置
        lineToBottom.constant = -scanBackground.frame.height
        
        //设置动画
        UIView.animateWithDuration(3, animations: {
            //设置重复
            UIView.setAnimationRepeatCount(MAXFLOAT)
            self.view.layoutIfNeeded()
            
        }) { (bool : Bool) in
            
            print("回扫")
            
            
        }
        
    }
   
    
}


// MARK: - AVCaptureMetadataOutputObjectsDelegate
extension scanQRViewController : AVCaptureMetadataOutputObjectsDelegate {
    
    func captureOutput(captureOutput: AVCaptureOutput!, didOutputMetadataObjects metadataObjects: [AnyObject]!, fromConnection connection: AVCaptureConnection!) {
        
        guard metadataObjects.count > 0 else{
            
            return
        }
        
        for obj in metadataObjects {
            guard obj.isKindOfClass(AVMetadataMachineReadableCodeObject) else{
                
                return
            }
            
            let tmpObj = obj as! AVMetadataMachineReadableCodeObject
            
            //print(tmpObj.stringValue)
            //print(tmpObj.corners)
            
            let alert = UIAlertController(title: "识别结果", message: tmpObj.stringValue, preferredStyle: .Alert)
            let action = UIAlertAction(title: "好", style: .Default, handler: { (action: UIAlertAction) in
                self.dismissViewControllerAnimated(true, completion: nil)
            })
            alert.addAction(action)
            
            presentViewController(alert, animated: true, completion: nil)
            
            
        }
        
    }
    
    
}
上一篇下一篇

猜你喜欢

热点阅读