QR Code 用于在 Twitter 和 Snapchat 等 app 中共享内容或添加新用户。从 iOS 11开始,用户可以使用内置的相机应用程序扫描 QR Code,这使得在我们的 app 中集成 QR Code 更方便。
在 iOS 中生成 QR code
自从引入 CIQRCodeGenerator Core Image 过滤器(filter) 以来,在 iOS 中生成 QR code 比以往任何时候都更加容易。它可以为给定的输入字符串生成黑色或白色 QR 码。
guard let qrFilter = CIFilter(name: "CIQRCodeGenerator") else { return nil }
let qrData = absoluteString.data(using: String.Encoding.ascii)
qrFilter.setValue(qrData, forKey: "inputMessage")
let qrTransform = CGAffineTransform(scaleX: 12, y: 12)
let qrImage = qrFilter.outputImage?.transformed(by: qrTransform)
这样,这个 QR 码就可以使用了,但它还不够吸引人。我们还可以对其进行自定义以适应我们 app 的设计风格。
更改 QR 码的颜色
定制 QR 码的第一步是更改颜色。我们分步进行操作:
- 反转黑白颜色
- 将黑色遮罩为透明
- 改变颜色
为了使此代码更易于使用,我们在 CIImage上创建 extension。
extension CIImage {
/// Inverts the colors and creates a transparent image by converting the mask to alpha.
/// Input image should be black and white.
var transparent: CIImage? {
return inverted?.blackTransparent
}
/// Inverts the colors.
var inverted: CIImage? {
guard let invertedColorFilter = CIFilter(name: "CIColorInvert") else { return nil }
invertedColorFilter.setValue(self, forKey: "inputImage")
return invertedColorFilter.outputImage
}
/// Converts all black to transparent.
var blackTransparent: CIImage? {
guard let blackTransparentFilter = CIFilter(name: "CIMaskToAlpha") else { return nil }
blackTransparentFilter.setValue(self, forKey: "inputImage")
return blackTransparentFilter.outputImage
}
/// Applies the given color as a tint color.
func tinted(using color: UIColor) -> CIImage?
{
guard
let transparentQRImage = transparent,
let filter = CIFilter(name: "CIMultiplyCompositing"),
let colorFilter = CIFilter(name: "CIConstantColorGenerator") else { return nil }
let ciColor = CIColor(color: color)
colorFilter.setValue(ciColor, forKey: kCIInputColorKey)
let colorImage = colorFilter.outputImage
filter.setValue(colorImage, forKey: kCIInputImageKey)
filter.setValue(transparentQRImage, forKey: kCIInputBackgroundImageKey)
return filter.outputImage!
}
}
QR 码通常链接到特定 URL,因此,也可以在 URL 上创建 extension 。
extension URL {
/// Creates a QR code for the current URL in the given color.
func qrImage(using color: UIColor) -> CIImage? {
return qrImage?.tinted(using: color)
}
/// Returns a black and white QR code for this URL.
var qrImage: CIImage? {
guard let qrFilter = CIFilter(name: "CIQRCodeGenerator") else { return nil }
let qrData = absoluteString.data(using: String.Encoding.ascii)
qrFilter.setValue(qrData, forKey: "inputMessage")
let qrTransform = CGAffineTransform(scaleX: 12, y: 12)
return qrFilter.outputImage?.transformed(by: qrTransform)
}
}
使用方法如下:
let swiftLeeOrangeColor = UIColor(red:0.93, green:0.31, blue:0.23, alpha:1.00)
let qrURLImage = URL(string: "https://www.avanderlee.com")?.qrImage(using: swiftLeeOrangeColor)
彩色 QR code
为 QR code 添加自定义 logo
由于 QR 码具有一定的错误纠正(error correction)
功能,因此我们可以用自定义 logo 替换其中的某些部分。为此,我们在 CIImage上创建另一个扩展,该扩展使用我们的 logo 并返回一个新的 CIImage:
extension CIImage {
/// Combines the current image with the given image centered.
func combined(with image: CIImage) -> CIImage? {
guard let combinedFilter = CIFilter(name: "CISourceOverCompositing") else { return nil }
let centerTransform = CGAffineTransform(translationX: extent.midX - (image.extent.size.width / 2), y: extent.midY - (image.extent.size.height / 2))
combinedFilter.setValue(image.transformed(by: centerTransform), forKey: "inputImage")
combinedFilter.setValue(self, forKey: "inputBackgroundImage")
return combinedFilter.outputImage!
}
}
结合我们更新的 URL 扩展,我们可以创建一个包括自定义 logo 的 QR 码。
extension URL {
/// Creates a QR code for the current URL in the given color.
func qrImage(using color: UIColor, logo: UIImage? = nil) -> CIImage? {
let tintedQRImage = qrImage?.tinted(using: color)
guard let logo = logo?.cgImage else {
return tintedQRImage
}
return tintedQRImage?.combined(with: CIImage(cgImage: logo))
}
}
let swiftLeeOrangeColor = UIColor(red:0.93, green:0.31, blue:0.23, alpha:1.00)
let swiftLeeLogo = UIImage(named: "swiftlee_qr_logo.png")!
let qrURLImage = URL(string: "https://www.avanderlee.com")?.qrImage(using: swiftLeeOrangeColor, logo: swiftLeeLogo)
A QR Code generated in Swift using a custom color and logo
网友评论