项目终于不需要支持iOS6了(泪崩),在二维码扫描这一块,能够完全的放弃ZXing库,改用系统的AVFoundation了,拿swift写了个Demo,效果如下:
github地址:点这里

有关AVFoundationCore Image(滤镜等),可以先看看objc.io第21期和第23期的有关介绍.

初始化视频捕捉

// 初始化视频捕获
    private func initCapture() {
        // 代表抽象的硬件设备,这里传入video
        let captureDevice = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo)
        var error: NSError?
        // 输入流
        var captureInput = AVCaptureDeviceInput.deviceInputWithDevice(captureDevice,error: &error) as? AVCaptureDeviceInput
        if (error != nil && captureInput == nil) {
            let errorAlert = UIAlertController(title: "提醒",message: "请在iPhone的\"设置-隐私-相机\"选项中,允许XXX访问您的相机",preferredStyle: .Alert)
            errorAlert.addAction(UIAlertAction(title: "确定",style: UIAlertActionStyle.Default,handler: nil))
            self.presentViewController(errorAlert,animated: true,completion: nil)
        } else {
            // input和output的桥梁,它协调着intput到output的数据传输.(见字意,session-会话)
            captureSession = AVCaptureSession()
            captureSession!.addInput(captureInput)

            // 输出流
            let captureMetadataOutput = AVCaptureMetadataOutput()
            // 限制扫描区域http://blog.csdn.net/lc_obj/article/details/41549469
            captureMetadataOutput.rectOfInterest = CGRectMake(128.0/ScreenWH.screenHeight,(ScreenWH.screenWidth - 280.0)/ScreenWH.screenWidth * 2.0,280.0/ScreenWH.screenHeight,280.0/ScreenWH.screenWidth)
            captureSession!.addOutput(captureMetadataOutput)
            // 添加的队列按规定必须是串行
            captureMetadataOutput.setMetadataObjectsDelegate(self,queue: dispatch_get_main_queue())
            // 指定信息类型,QRCode,你懂的
            captureMetadataOutput.MetadataObjectTypes = [AVMetadataObjectTypeQRCode]

            // 用这个预览图层和图像信息捕获会话(session)来显示视频
            videoPreviewLayer = AVCaptureVideoPreviewLayer(session: captureSession!)
            videoPreviewLayer!.videoGravity = AVLayerVideoGravityResizeAspectFill
            videoPreviewLayer!.frame = view.bounds
            view.layer.addSublayer(videoPreviewLayer!)
        }
    }

PS:LZ用了下微信和新浪微博的扫一扫,发现那个扫描框是忽悠人的,也就是你没拿它对准二维码,只要二维码进入手机摄像头范围,就能够解码成功….囧
所以LZ在代码中做了一个扫描区域的限制(感觉蛮无聊的)

实现代理解码

// MARK: - AVCaptureMetadataOutputObjectsDelegate
    func captureOutput(captureOutput: AVCaptureOutput!,didOutputMetadataObjects MetadataObjects: [AnyObject]!,fromConnection connection: AVCaptureConnection!) {
        if MetadataObjects == nil || MetadataObjects.count == 0 {
            captureView!.frame = CGRectZero
            return
        }
        // 刷取出来的数据
        for MetadataObject in MetadataObjects {
            if MetadataObject.type == AVMetadataObjectTypeQRCode {
                let Metadata = MetadataObject as! AVMetadataMachineReadableCodeObject
                // 元数据对象就会被转化成图层的坐标
                let codeCoord = videoPreviewLayer!.transformedMetadataObjectForMetadataObject(Metadata) as! AVMetadataMachineReadableCodeObject
                captureView!.frame = codeCoord.bounds
                if Metadata.stringValue != nil {
                    println("\(Metadata.stringValue)")
                    self.captureSession!.stopRunning()
                    let successAlert = UIAlertController(title:"提示",message:"是否打开" + Metadata.stringValue,preferredStyle: .Alert)
                    successAlert.addAction(UIAlertAction(title:"取消",style: .Default,handler: { (_) -> Void in self.stopCapture() })) successAlert.addAction(UIAlertAction(title:"确定",handler: { (_) -> Void in if Metadata.stringValue.lowercaseString.hasPrefix("http") { UIApplication.sharedApplication().openURL(NSURL(string: Metadata.stringValue)!) self.navigationController!.popViewControllerAnimated(true) } })) self.presentViewController(successAlert,animated: true,completion: nil) } } } }

数据转换AVMetadataMachineReadableCodeObject对应二维码.

生成二维码

// MARK: - Private Methods
    private 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
    }

如图

结尾:AVFoundation这个框架特别的强大,也可以用它来写自定义相机,拍照和录制视频等

Swift AVFoundation 二维码扫描和生成的更多相关文章

  1. 手对手的教你用canvas画一个简单的海报的方法示例

    企业的广告投入开始从电视等传统媒体向基于圈层文化的新媒体精准营销转移,很多人都想制作一张属于自己的海报,本文介绍了手对手的教你用canvas画一个简单的海报的方法示例,感兴趣的可以了解一下

  2. 详解Canvas实用库Fabric.js使用手册

    这篇文章主要介绍了详解Canvas实用库Fabric.js使用手册的相关资料,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  3. 【HTML5】3D模型--百行代码实现旋转立体魔方实例

    本篇文章主要介绍【HTML5】3D模型--百行代码实现旋转立体魔方实例,具有一定的参考价值,有需要的可以了解一下。

  4. H5 canvas实现贪吃蛇小游戏

    本篇文章主要介绍了H5 canvas实现贪吃蛇小游戏,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  5. ios – 如何更改UINavigationBar底部边框的颜色?

    我阅读了许多主题,但没有一个在最新版本的Swift的清晰,一致的答案中解决了这个问题.例如,thisquestion的最佳答案表明UINavigationBar.appearance().setShadowImage().但是,最新版本的swift中不存在这样的方法.我不想隐藏底部边框.我只是想改变颜色.另外,能够改变高度会很棒,但我知道我在一个问题上问得太多了.编辑:我创建了一个2×1像素图像并

  6. ios – sizeToFit削减了一些UILabel字体类型的高度和宽度但不是其他 – 是否有修复?

    我正在使用自定义字体,我有一点障碍.有些字体可以正常使用sizetoFit,如下所示:但是,其他自定义字体在左侧和底部被截断,因为这是:我可以“破解”它,只检查每种字体类型并添加几个像素,但我想知道是否有更清晰的解决方案,甚至解释为什么会发生这种情况.谢谢!

  7. ios – UILabel子类 – 尽管标签高度正确,文字在底部切断

    我有一个问题,UILabel子类切断底部的文本.标签的高度适合文本,底部留有一些空间,但文本仍然被剪掉.红色条纹是添加到标签图层的边框.我将标签子类化以添加边缘插入.但是,在这种特殊情况下,插入是零.解决方法事实证明问题在于改变它解决了这个问题

  8. ios – performBatchUpdates上的UICollectionView性能问题

    我们正在尝试使用自定义布局设置UICollectionView.每个CollectionViewCell的内容都是一个图像.总之,将会有数千张图像,并且在某个特定时间可以看到大约140-150张图像.在动作事件中,可能会在位置和大小上重新组织所有单元格.目标是使用performBatchUpdates方法为当前所有移动事件设置动画.在一切变得动画之前,这会导致很长的延迟时间.到目前为止,我们发现内

  9. ios – 当我缩放时,如何关闭所有图像处理以查看实际的未修改像素?

    我有一个应用程序需要放大到足够远的图像,我可以清楚地看到图像上的单个像素.我需要看到一种颜色的清晰正方形,没有抗锯齿或其他通常有用的技术,使图像在显示器上看起来很好.我如何扼杀所有这些帮助?

  10. 如何清除屏幕截图IOS

    我正在研究IOS应用程序,其中需要采取清晰的屏幕截图我已经尝试过了但是图像的质量并不好.请为我推荐一些东西.解决方法换线至

随机推荐

  1. Swift UITextField,UITextView,UISegmentedControl,UISwitch

    下面我们通过一个demo来简单的实现下这些控件的功能.首先,我们拖将这几个控件拖到storyboard,并关联上相应的属性和动作.如图:关联上属性和动作后,看看实现的代码:

  2. swift UISlider,UIStepper

    我们用两个label来显示slider和stepper的值.再用张图片来显示改变stepper值的效果.首先,这三个控件需要全局变量声明如下然后,我们对所有的控件做个简单的布局:最后,当slider的值改变时,我们用一个label来显示值的变化,同样,用另一个label来显示stepper值的变化,并改变图片的大小:实现效果如下:

  3. preferredFontForTextStyle字体设置之更改

    即:

  4. Swift没有异常处理,遇到功能性错误怎么办?

    本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请发送邮件至dio@foxmail.com举报,一经查实,本站将立刻删除。

  5. 字典实战和UIKit初探

    ios中数组和字典的应用Applicationschedule类别子项类别名称优先级数据包contactsentertainment接触UIKit学习用Swift调用CocoaTouchimportUIKitletcolors=[]varbackView=UIView(frame:CGRectMake(0.0,0.0,320.0,CGFloat(colors.count*50)))backView

  6. swift语言IOS8开发战记21 Core Data2

    上一话中我们简单地介绍了一些coredata的基本知识,这一话我们通过编程来实现coredata的使用。还记得我们在coredata中定义的那个Model么,上面这段代码会加载这个Model。定义完方法之后,我们对coredata的准备都已经完成了。最后强调一点,coredata并不是数据库,它只是一个框架,协助我们进行数据库操作,它并不关心我们把数据存到哪里。

  7. swift语言IOS8开发战记22 Core Data3

    上一话我们定义了与coredata有关的变量和方法,做足了准备工作,这一话我们来试试能不能成功。首先打开上一话中生成的Info类,在其中引用头文件的地方添加一个@objc,不然后面会报错,我也不知道为什么。

  8. swift实战小程序1天气预报

    在有一定swift基础的情况下,让我们来做一些小程序练练手,今天来试试做一个简单地天气预报。然后在btnpressed方法中依旧增加loadWeather方法.在loadWeather方法中加上信息的显示语句:运行一下看看效果,如图:虽然显示出来了,但是我们的text是可编辑状态的,在storyboard中勾选Editable,再次运行:大功告成,而且现在每次单击按钮,就会重新请求天气情况,大家也来试试吧。

  9. 【iOS学习01】swift ? and !  的学习

    如果不初始化就会报错。

  10. swift语言IOS8开发战记23 Core Data4

    接着我们需要把我们的Rest类变成一个被coredata管理的类,点开Rest类,作如下修改:关键字@NSManaged的作用是与实体中对应的属性通信,BinaryData对应的类型是NSData,CoreData没有布尔属性,只能用0和1来区分。进行如下操作,输入类名:建立好之后因为我们之前写的代码有些地方并不适用于coredata,所以编译器会报错,现在来一一解决。

返回
顶部