swift 二维码的生成

2016-11-10  本文已影响525人  估唔到

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

首先先明确思路

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
上一篇下一篇

猜你喜欢

热点阅读