Swift:使用系统AVFoundation实现二维码扫描和生成

原创 2015年07月08日 16:50:49

系统提供的AVCaptureSession只适用于iOS7.0以上的系统;之前的请用Zbar来替代

下载地址:http://download.csdn.net/detail/huobanbengkui/8881097

配置工程:

引入:

import Foundation
import AVFoundation

接受AVCaptureMetadataOutputObjectsDelegate(如: class QrcodeVC: UIViewController,AVCaptureMetadataOutputObjectsDelegate, UIAlertViewDelegate)

定义属性:

    let device = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo)
    let session = AVCaptureSession()
    var layer: AVCaptureVideoPreviewLayer?

一. 二维码扫描

1.使用相机捕捉二维码

func setupCamera(){
        self.session.sessionPreset = AVCaptureSessionPresetHigh
        var error : NSError?
        let input = AVCaptureDeviceInput(device: device, error: &error)
        if (error != nil && input == nil) {
            var errorAlert = UIAlertView(title: "提醒", message: "请在iPhone的\"设置-隐私-相机\"选项中,允许本程序访问您的相机", delegate: self, cancelButtonTitle: "确定")
                errorAlert.show()
            return
        }
        if session.canAddInput(input) {
            session.addInput(input)
        }
        layer = AVCaptureVideoPreviewLayer(session: session)
        layer!.videoGravity = AVLayerVideoGravityResizeAspectFill
        //可以看到的镜头区域
        layer!.frame = CGRectMake(0, 0,320,568)
        self.view.layer.insertSublayer(self.layer, atIndex: 0)
        
        let output = AVCaptureMetadataOutput()
        //设置响应区域
        //        output.rectOfInterest = CGRectMake(0, 0, 0, 0)
        output.setMetadataObjectsDelegate(self, queue: dispatch_get_main_queue())
        if session.canAddOutput(output) {
            session.addOutput(output)
            output.metadataObjectTypes = [AVMetadataObjectTypeQRCode];
        }
        
        session.startRunning()
    }

2.识别二维码以后,解析数据(实现AVCaptureMetadataOutputObjectsDelegate的代理方法)

func captureOutput(captureOutput: AVCaptureOutput!, didOutputMetadataObjects metadataObjects: [AnyObject]!, fromConnection connection: AVCaptureConnection!) {
        
        var stringValue:String?
        if metadataObjects.count > 0 {
            var metadataObject = metadataObjects[0] as!AVMetadataMachineReadableCodeObject
            stringValue = metadataObject.stringValue
            
            if stringValue != nil{
                self.session.stopRunning()
                
                
            }
        }
        self.session.stopRunning()
        var alertView = UIAlertView(title: "二维码", message: stringValue, delegate: self, cancelButtonTitle: "确定")
        alertView.show()
    }

最后在页面消失的时候:

override func viewWillDisappear(animated: Bool) {
        super.viewWillDisappear(animated)
        
        if self.session.running {
            self.session.stopRunning()
        }
    }

二. 二维码生成

func createQRForString(qrString: String?, qrImageName: String?) -> UIImage?{
        if let sureQRString = qrString {
            let stringData = sureQRString.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)
            // 创建一个二维码的滤镜
            let qrFilter = CIFilter(name: "CIQRCodeGenerator")
            qrFilter.setValue(stringData, forKey: "inputMessage")
            qrFilter.setValue("H", forKey: "inputCorrectionLevel")
            let qrCIImage = qrFilter.outputImage
            // 创建一个颜色滤镜,黑白色
            let colorFilter = CIFilter(name: "CIFalseColor")
            colorFilter.setDefaults()
            colorFilter.setValue(qrCIImage, forKey: "inputImage")
            colorFilter.setValue(CIColor(red: 0, green: 0, blue: 0), forKey: "inputColor0")
            colorFilter.setValue(CIColor(red: 1, green: 1, blue: 1), forKey: "inputColor1")
            // 返回二维码image
            let codeImage = UIImage(CIImage: colorFilter.outputImage.imageByApplyingTransform(CGAffineTransformMakeScale(5, 5)))
            // 通常,二维码都是定制的,中间都会放想要表达意思的图片
            if let iconImage = UIImage(named: qrImageName!) {
                let rect = CGRectMake(0, 0, codeImage!.size.width, codeImage!.size.height)
                UIGraphicsBeginImageContext(rect.size)
                
                codeImage!.drawInRect(rect)
                let avatarSize = CGSizeMake(rect.size.width * 0.25, rect.size.height * 0.25)
                let x = (rect.width - avatarSize.width) * 0.5
                let y = (rect.height - avatarSize.height) * 0.5
                iconImage.drawInRect(CGRectMake(x, y, avatarSize.width, avatarSize.height))
                let resultImage = UIGraphicsGetImageFromCurrentImageContext()
                
                UIGraphicsEndImageContext()
                return resultImage
            }
            return codeImage
        }
        return nil
    }

如何使用呢??

var imageViewIcon = UIImageView(frame: CGRectMake(100, 100, 150, 150))
        imageViewIcon.image = createQRForString("好好", qrImageName: "ocrBack") //“ocrBack” 放入二维码中间图片的名字
        self.view.addSubview(imageViewIcon)

如图:

最后说明:

AVFoundation框架不仅支持二维码扫描,还支持很多别的条码类别,例如Code39,Code128,Aztec,和PDF417。大家可以尝试修改。


版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

使用系统提供的AVFoundation 实现二维码扫描(带动画)

注意这里的扫描必须真机测试 模拟器上是看不出来效果的 #import "ViewController.h" #import @interface ViewController ()...

Swift AVFoundation 二维码扫描和生成

title: Swift AVFoundation 二维码扫描和生成 date: 2015-03-16 08:46:28 categories: Swifttags: AVFoundation 二...

iOS 开发AVFoundation系统原生二维码扫描实现

iOS 开发AVFoundation系统原生二维码扫描实现

IOS下使用AVFoundation实现条形码和二维码扫描

IOS下使用AVFoundation实现条形码和二维码扫描

iOS 使用AVFoundation 扫描二维码并限定扫描区域(带代码生成蒙版)

使用AVFoundation 生成的二维码扫描器,扫描速度快,加上扫描限定区域缩小扫描范围,另外代码直接在扫描区域外生成黑色透明蒙版,简单扫描动画。相册相片识别二维码信息(只支持ios8及以上版本)。...
  • Airrons
  • Airrons
  • 2015年09月29日 11:36
  • 2108

利用AVFoundation实现二维码扫描以及其中的问题

二维码扫描中的问题
  • rxl_dhf
  • rxl_dhf
  • 2016年04月18日 23:05
  • 452

使用AVFoundation完成二维码扫描

其中有几点需要注意的 1.应该使用异步线程来配置那几个属性,这样可以防止阻塞主线程加载UI。 2.output的rectOfInterst是感应区域,就是说,在这个区域内才有扫描效果。但是由于摄像...

用AVFoundation实现扫描二维码功能

需要用到的只要几个类: AVCaptureSession:管理输入和输出流,包含开启和停止会话方法 AVCaptureDeviceInput:是AVCaptureInput的子类,可以作为输入捕获...

iOS二维码生成与扫描(zbar和原生AVFoundation)

公司iOS项目需要用到二维码扫描,本来已经有人写好了,但是扫描速度不太快,于是让我接手研究一下。之前也没接触过二维码扫描,写这篇博客献给新手。 先来二维码生成吧,二维码生成需要libqrencode库...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Swift:使用系统AVFoundation实现二维码扫描和生成
举报原因:
原因补充:

(最多只允许输入30个字)