美文网首页
swift 二维码的生成

swift 二维码的生成

作者: 估唔到 | 来源:发表于2016-11-10 23:48 被阅读525次

    首先简单介绍一下二维码。二维码: 是用某种特定的几何图形按一定规律在平面(二维方向上)分布的黑白相间的图形,用于记录数据符号信息。在当今估计手机族对二维码肯定不会陌生,二维码支付已经无处不在,而且大多数APP都具备了扫码功能。不过二维码的生成方式要稍微注意下,苹果从iOS7开始集成了二维码的生成和读取功能;此前被广泛使用的zbarsdk和zxing目前不支持64位处理器,而且2015年2月1号起, 不允许不支持64位处理器的APP 上架。下面介绍一下用swift实现二维码的生成。

    首先先明确思路

    • 1.获取内容
    • 2.创建一个二维码滤镜
    • 3.设置内容
    • 4.设置二维码的级别(纠错率)
    • 5.从二维码滤镜中获取二维码
    • 6.展示图片
    Snip20161110_13.png

    这里用到一个UITextView作为输入框,上面用一个250*250的UIImageView作为二维码的展示框

        @IBOutlet weak var imageV: UIImageView!
        @IBOutlet weak var textF: UITextView!
    
        // 1.获取内容
        let contentStr = textF.text
        if contentStr?.characters.count == 0 {return}
        
        // 2.创建一个二维码滤镜
        guard let filter = CIFilter(name: "CIQRCodeGenerator") else {
            return
        }
    
        // 3.设置内容
        // 注意点
        // 如果要设置二维码内容,必须以KVC的方式设置
        // 二维码的值必须是NSData
        let data = contentStr?.data(using: .utf8)
        filter.setValue(data, forKeyPath: "inputMessage")
        
        // 4.设置二维码的级别(纠错率)
        //        key : inputCorrectionLevel
        //        value L: 7% M(默认  ): 15% Q: 25% H: 30%
        filter.setValue("H", forKeyPath: "inputCorrectionLevel")
        
        // 5.从二维码滤镜中获取二维码
        guard let outPutImage = filter.outputImage else{return}
        
        // 6.展示图片
        let imageUI = UIImage(ciImage: outPutImage)
        imageV.image = imageUI
    

    图片展示后我们会发现一个小小的问题,生成的二维码图片的大小为23×23,放大到250×250就会变得很模糊,这里可以用到一个大神封装好的方法,可以将模糊的二维码图片转为清晰的。

      其中传入的几个参数
      /// - parameter image: 模糊的二维码图片
      /// - parameter size: 需要生成的二维码尺寸
      /// - returns: 清晰的二维码图片
    
        fileprivate func createClearImage(_ image : CIImage, size : CGFloat ) -> UIImage? {
        
        // 1.调整小数像素到整数像素,将origin下调(12.*->12),size上调(11.*->12)
        let extent = image.extent.integral
        
        // 2.将指定的大小与宽度和高度进行对比,获取最小的比值
        let scale = min(size / extent.width, size/extent.height)
        
        // 3.将图片放大到指定比例
        let width = extent.width * scale
        let height = extent.height * scale
        // 3.1创建依赖于设备的灰度颜色通道
        let cs = CGColorSpaceCreateDeviceGray();
        // 3.2创建位图上下文
        let bitmapRef = CGContext(data: nil, width: Int(width), height: Int(height), bitsPerComponent: 8, bytesPerRow: 0, space: cs, bitmapInfo: 0)
        
        // 4.创建上下文
        let context = CIContext(options: nil)
        
        // 5.将CIImage转为CGImage
        let bitmapImage = context.createCGImage(image, from: extent)
        
        // 6.设置上下文渲染等级
        bitmapRef!.interpolationQuality = .none
        
        // 7.改变上下文的缩放
        bitmapRef?.scaleBy(x: scale, y: scale)
        
        // 8.绘制一张图片在位图上下文中
        bitmapRef?.draw(bitmapImage!, in: extent)
        
        // 9.从位图上下文中取出图片(CGImage)
        guard let scaledImage = bitmapRef?.makeImage() else {return nil}
        
        // 10.将CGImage转为UIImage并返回
        return UIImage(cgImage: scaledImage)
    }
    

    在生成二维码时,我们还可以根据需要设置它的颜色,不过这里也有一个注意点:设置二维码颜色,必须放在清晰的二维码之后,如果先设置颜色,再改变清晰度,则设置颜色无效。先把之前展示图片的代码注释掉,设置完成后再展示。

        guard let imageUI = createClearImage(outPutImage, size: imageV.bounds.height) else{return}
        
        // 设置二维码颜色
        let imageCI = CIImage(image: imageUI)
        let colorFilter = CIFilter(name:"CIFalseColor")
        colorFilter?.setDefaults()
    
        // 设置图片
        colorFilter?.setValue(imageCI, forKeyPath: "inputImage")
        // 设置二维码颜色
        colorFilter?.setValue(CIColor.init(color: UIColor.blue), forKeyPath: "inputColor0")
        
        // 设置背景颜色
        colorFilter?.setValue(CIColor.init(color: UIColor.green), forKeyPath: "inputColor1")
        guard let colorOutPutImage = colorFilter?.outputImage else {
            return
        }
        imageV.image = UIImage(ciImage: colorOutputImage)
    
    Snip20161110_14.png

    这里再额外补充一个,有时候我们需要在二维码中间插入图片,那么我们就需要自定义二维码,但是自定义时有个注意点:二维码可以遮挡部分区域,但是要保证三个角不能被遮挡,三个角用于扫描定位(用户可能斜着拍\\\\\\\\倒着拍)

        fileprivate func createCustomImage(bigImage : UIImage, smallImage : UIImage, smallImageWH : CGFloat) -> UIImage? {
        
        // 0.获取大图片的尺寸
        let bigImageSize = bigImage.size
        
        // 1.创建图形上下文
        UIGraphicsBeginImageContext(bigImageSize)
        
        // 2.绘制大图片
        bigImage.draw(in: CGRect(x: 0, y: 0, width: bigImageSize.width, height: bigImageSize.height))
        
        // 3.绘制小图片
        smallImage.draw(in: CGRect(x: (bigImageSize.width - smallImageWH) * 0.5, y: (bigImageSize.height - smallImageWH) * 0.5, width: smallImageWH, height: smallImageWH))
        
        // 4.从上下文取出图片
        let outImage = UIGraphicsGetImageFromCurrentImageContext()
        
        // 5.关闭上下文
        UIGraphicsEndImageContext()
        
        return outImage
    }
    

    只需要传入二维码的大图片,中间需要显示的小图片,以及小图片尺寸三个参数,便能生成自定义二维码。

    Snip20161110_15.png

    相关文章

      网友评论

          本文标题:swift 二维码的生成

          本文链接:https://www.haomeiwen.com/subject/vafouttx.html