首先简单介绍一下二维码。二维码: 是用某种特定的几何图形按一定规律在平面(二维方向上)分布的黑白相间的图形,用于记录数据符号信息。在当今估计手机族对二维码肯定不会陌生,二维码支付已经无处不在,而且大多数APP都具备了扫码功能。不过二维码的生成方式要稍微注意下,苹果从iOS7开始集成了二维码的生成和读取功能;此前被广泛使用的zbarsdk和zxing目前不支持64位处理器,而且2015年2月1号起, 不允许不支持64位处理器的APP 上架。下面介绍一下用swift实现二维码的生成。
首先先明确思路
- 1.获取内容
- 2.创建一个二维码滤镜
- 3.设置内容
- 4.设置二维码的级别(纠错率)
- 5.从二维码滤镜中获取二维码
- 6.展示图片
这里用到一个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)
这里再额外补充一个,有时候我们需要在二维码中间插入图片,那么我们就需要自定义二维码,但是自定义时有个注意点:二维码可以遮挡部分区域,但是要保证三个角不能被遮挡,三个角用于扫描定位(用户可能斜着拍\\\\\\\\倒着拍)
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
}
只需要传入二维码的大图片,中间需要显示的小图片,以及小图片尺寸三个参数,便能生成自定义二维码。