QR Code is used a lot to share content or add new users in apps like Twitter and Snapchat. Starting with iOS 11, users can scan QR codes with the camera app built into iOS. And iOS can also generate QR codes for embedded content.
1. Proceed to create QR code in iOS
Creating QR codes in iOS is easier than ever since the introduction of the CIQRCodeGenerator
core image filter. It generates a simple black and white QR code for the given input string. We do the following:
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 works, but it doesn’t look very appealing and it probably won’t suit your app design. Hence, it would be really great if we could customize it ourselves to suit our application design.
2. Perform color change of the QR code
The first step in customizing the QR code is to change the colors. We’ll do this in three steps:
- Invert black and white
- Cover black to transparent
- Change color
To make this code easier to use, we will create an extension for 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) } } |
Or the QR code can be generated from any String, we add the following method to use in this case:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
func generateQrCode(_ content: String) -> CIImage? { let data = content.data(using: String.Encoding.ascii, allowLossyConversion: false) let filter = CIFilter(name: "CIQRCodeGenerator") filter?.setValue(data, forKey: "inputMessage") filter?.setValue("Q", forKey: "inputCorrectionLevel") if let qrCodeImage = (filter?.outputImage){ return qrCodeImage } return nil } |
We proceed to generate a QR code from the URL with the following blue color:
1 2 3 4 |
let color = UIColor(red:0.08380651384, green:0.4750699216, blue:0.9372549057, alpha:1.00) guard let qrURLImage = URL(string: "https://www.google.com")?.qrImage(using: color) else { return } imageQR.image = UIImage(ciImage: qrURLImage) |
And this is the result :
3. QR code with custom logo
To make it a truly outstanding QR code, we can add our own custom little logo inside the QR CIImage
using a UIImage extension:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
extension UIImage { /// place the imageView inside a container view /// - parameter superView: the containerView that you want to place the Image inside /// - parameter width: width of imageView, if you opt to not give the value, it will take default value of 100 /// - parameter height: height of imageView, if you opt to not give the value, it will take default value of 30 func addToCenter(of superView: UIView, width: CGFloat = 100, height: CGFloat = 30) { let overlayImageView = UIImageView(image: self) overlayImageView.translatesAutoresizingMaskIntoConstraints = false overlayImageView.contentMode = .scaleAspectFit superView.addSubview(overlayImageView) let centerXConst = NSLayoutConstraint(item: overlayImageView, attribute: .centerX, relatedBy: .equal, toItem: superView, attribute: .centerX, multiplier: 1, constant: 0) let width = NSLayoutConstraint(item: overlayImageView, attribute: .width, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1, constant: 100) let height = NSLayoutConstraint(item: overlayImageView, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1, constant: 30) let centerYConst = NSLayoutConstraint(item: overlayImageView, attribute: .centerY, relatedBy: .equal, toItem: superView, attribute: .centerY, multiplier: 1, constant: 0) NSLayoutConstraint.activate([width, height, centerXConst, centerYConst]) } } |
Note: When you try to set the width / height of the logo to be small, make sure it’s not too big, otherwise it will make the QR code unreadable.
We proceed to fully implement the code as follows:
1 2 3 4 5 6 7 |
let doremonLogo = UIImage(named: "doraemon.png")! let color = UIColor(red:0.08380651384, green:0.4750699216, blue:0.9372549057, alpha:1.00) guard let qrURLImage = URL(string: "https://www.google.com")?.qrImage(using: color) else { return } imageQR.image = UIImage(ciImage: qrURLImage) doremonLogo.addToCenter(of: imageQR) |
And here is the result:
4. Conclusion
Creating QR codes with custom colors and logos will make your app more attractive and beautiful to match your app design. Hopefully, this will help you in coding more efficiently.
So my post here is over. Thank you for watching the article.