Generador de códigos QR en Swift: Core Image, CIFilter y soluciones personalizadas

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Generación de códigos QR en Swift (iOS/macOS): desde Core Image hasta soluciones personalizadas

\n\n

Los códigos QR se han convertido en una parte esencial de las aplicaciones modernas, desde la transmisión de enlaces hasta la autenticación y el pago. En las plataformas de Apple (iOS, macOS, watchOS, tvOS) existe una potente herramienta integrada para generar códigos QR: el framework Core Image con el filtro CIQRCodeGenerator. En este artículo, analizaremos en detalle cómo crear tu propio generador de códigos QR en Swift, incluyendo la configuración de color, tamaño, la adición de un logotipo y la integración con SwiftUI.

\n\n

Fundamentos: Core Image y CIQRCodeGenerator

\n\n

Core Image es un framework integrado de Apple para el procesamiento de imágenes. El filtro CIQRCodeGenerator permite crear un código QR a partir de cualquier cadena (URL, texto, datos de contacto). Admite corrección de errores (niveles L, M, Q, H) y codificación de hasta 7089 caracteres (dependiendo del nivel de corrección).

\n\n

Ejemplo básico de generación de un código QR como UIImage:

\n\n
import UIKit\nimport CoreImage\n\nfunc generateQRCode(from string: String) -> UIImage? {\n    let data = string.data(using: .utf8)\n    guard let filter = CIFilter(name: "CIQRCodeGenerator") else { return nil }\n    filter.setValue(data, forKey: "inputMessage")\n    filter.setValue("H", forKey: "inputCorrectionLevel") // Corrección de errores máxima\n    \n    guard let outputImage = filter.outputImage else { return nil }\n    \n    // Aumentamos la resolución (por defecto es pequeña)\n    let transform = CGAffineTransform(scaleX: 10, y: 10)\n    let scaledImage = outputImage.transformed(by: transform)\n    \n    return UIImage(ciImage: scaledImage)\n}\n\n// Uso\nif let qrImage = generateQRCode(from: "https://pythonlib.ru") {\n    // Mostramos qrImage en UIImageView\n}
\n\n

Configuración de color y fondo

\n\n

Por defecto, el código QR es blanco y negro. Para cambiar los colores, es necesario convertir CIImage a UIImage y luego realizar un relleno usando Core Graphics o CIFilter. La forma más sencilla es usar CIFalseColor:

\n\n
func generateColoredQRCode(from string: String, color: UIColor, backgroundColor: UIColor) -> UIImage? {\n    guard let data = string.data(using: .utf8),\n          let qrFilter = CIFilter(name: "CIQRCodeGenerator") else { return nil }\n    qrFilter.setValue(data, forKey: "inputMessage")\n    qrFilter.setValue("M", forKey: "inputCorrectionLevel")\n    \n    guard let qrImage = qrFilter.outputImage else { return nil }\n    \n    // Aplicamos el filtro de color\n    let colorFilter = CIFilter(name: "CIFalseColor")\n    colorFilter?.setValue(qrImage, forKey: "inputImage")\n    colorFilter?.setValue(CIColor(color: color), forKey: "inputColor0")   // Color de los módulos\n    colorFilter?.setValue(CIColor(color: backgroundColor), forKey: "inputColor1") // Color de fondo\n    \n    guard let coloredImage = colorFilter?.outputImage else { return nil }\n    \n    let transform = CGAffineTransform(scaleX: 10, y: 10)\n    let scaledImage = coloredImage.transformed(by: transform)\n    \n    return UIImage(ciImage: scaledImage)\n}
\n\n

Añadir un logotipo en el centro del código QR

\n\n

Para el branding, a menudo es necesario insertar un logotipo en el centro. Esto reduce la legibilidad, por lo que es mejor usar un nivel alto de corrección de errores (H). El algoritmo: primero creamos el código QR, luego superponemos un UIImage con el logotipo encima.

\n\n
func generateQRWithLogo(from string: String, logo: UIImage, qrColor: UIColor = .black, bgColor: UIColor = .white) -> UIImage? {\n    guard let qrImage = generateColoredQRCode(from: string, color: qrColor, backgroundColor: bgColor) else { return nil }\n    \n    let qrSize = qrImage.size\n    let logoSize = CGSize(width: qrSize.width * 0.25, height: qrSize.height * 0.25) // 25% del QR\n    let logoOrigin = CGPoint(x: (qrSize.width - logoSize.width) / 2,\n                             y: (qrSize.height - logoSize.height) / 2)\n    \n    UIGraphicsBeginImageContextWithOptions(qrSize, fa                    

Recommendations