在Swift中生成QR码(iOS/macOS):从Core Image到自定义解决方案
QR码已成为现代应用程序不可或缺的一部分——从链接传输到身份验证和支付。在Apple平台(iOS、macOS、watchOS、tvOS)上,有一个内置的强大工具用于生成QR码——Core Image框架及其CIQRCodeGenerator滤镜。在本文中,我们将详细讲解如何使用Swift创建自己的QR码生成器,包括颜色、大小设置、添加Logo以及与SwiftUI的集成。
基础:Core Image与CIQRCodeGenerator
Core Image是Apple内置的图像处理框架。CIQRCodeGenerator滤镜允许从任何字符串(URL、文本、联系人数据)创建QR码。它支持错误校正(L、M、Q、H级别)以及最多7089个字符的编码(取决于校正级别)。
生成UIImage格式QR码的基本示例:
import UIKitimport CoreImage
func generateQRCode(from string: String) -> UIImage? { let data = string.data(using: .utf8) guard let filter = CIFilter(name: "CIQRCodeGenerator") else { return nil } filter.setValue(data, forKey: "inputMessage") filter.setValue("H", forKey: "inputCorrectionLevel") // 最大错误校正 guard let outputImage = filter.outputImage else { return nil } // 提高分辨率(默认较小) let transform = CGAffineTransform(scaleX: 10, y: 10) let scaledImage = outputImage.transformed(by: transform) return UIImage(ciImage: scaledImage)}
// 使用if let qrImage = generateQRCode(from: "https://pythonlib.ru") { // 在UIImageView中显示qrImage}设置颜色和背景
默认情况下,QR码是黑白的。要更改颜色,需要将CIImage转换为UIImage,然后使用Core Graphics或CIFilter进行填充。最简单的方法是使用CIFalseColor:
func generateColoredQRCode(from string: String, color: UIColor, backgroundColor: UIColor) -> UIImage? { guard let data = string.data(using: .utf8), let qrFilter = CIFilter(name: "CIQRCodeGenerator") else { return nil } qrFilter.setValue(data, forKey: "inputMessage") qrFilter.setValue("M", forKey: "inputCorrectionLevel") guard let qrImage = qrFilter.outputImage else { return nil } // 应用颜色滤镜 let colorFilter = CIFilter(name: "CIFalseColor") colorFilter?.setValue(qrImage, forKey: "inputImage") colorFilter?.setValue(CIColor(color: color), forKey: "inputColor0") // 模块颜色 colorFilter?.setValue(CIColor(color: backgroundColor), forKey: "inputColor1") // 背景颜色 guard let coloredImage = colorFilter?.outputImage else { return nil } let transform = CGAffineTransform(scaleX: 10, y: 10) let scaledImage = coloredImage.transformed(by: transform) return UIImage(ciImage: scaledImage)}在QR码中心添加Logo
为了品牌化,通常需要在中心插入Logo。这会降低可读性,因此最好使用高错误校正级别(H)。算法:首先创建QR码,然后在上面叠加带有Logo的UIImage。
func generateQRWithLogo(from string: String, logo: UIImage, qrColor: UIColor = .black, bgColor: UIColor = .white) -> UIImage? { guard let qrImage = generateColoredQRCode(from: string, color: qrColor, backgroundColor: bgColor) else { return nil } let qrSize = qrImage.size let logoSize = CGSize(width: qrSize.width * 0.25, height: qrSize.height * 0.25) // QR码的25% let logoOrigin = CGPoint(x: (qrSize.width - logoSize.width) / 2, y: (qrSize.height - logoSize.height) / 2) UIGraphicsBeginImageContextWithOptions(qrSize, fa