QR Code is used a lot to share content or add new users in apps like Twitter and Snapchat.
Since iOS 11, users can scan QR codes with the camera.
This makes integrating QR codes in your own apps even nicer.
QR code generation in iOS
QR code generation in iOS is easier than ever since Core Image CIQRCodeGenerator
filter. It generates a black and white QR for an input string string.
1 2 3 4 5 6 7 | 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) |
This QR code might work, but it’s not as appealing yet, and maybe you want it to look better.
Hence, I will show you how to customize it to fit my application design.
Change the color of the QR code
The first step in customizing the QR code is to change the colors. We do this in three steps:
- Invert the black and white
- Cover black to transparent
- Change color
To make this code easier to use, we create an extension of CIImage
.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | 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 codes usually link to a URL. Therefore, you should also create an extension for the URL.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | 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) } } |
And use it as follows:
1 2 3 | 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) |
The QR code has changed color:
Custom logo for QR code
To make it a truly outstanding QR code, we can add our own custom logo. QR codes allow us to replace a certain part of it with a custom logo. To do this, we create another CIImage
extension, use the logo, and return a new CIImage.
1 2 3 4 5 6 7 8 9 10 11 12 | 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! } } |
Combined with the newly updated URL extension, we can create a more beautiful new QR code including custom logo.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | 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) |
Achievement:
Hope it is useful to you, thank you for watching all the articles!
Source: medium.com