1

I have a custom QR code generator that is pretty simple right now. But, I want to do two things.

  1. Change the color of the QR code
  2. Change the shape of the individual squares (e.g. round the corners)

If anyone is familiar with custom QR code generation, I'd be so happy if you could help. Here's the code for the generator function:

func generateQRCode() {
        var urlString = Twitter.sharedInstance.firebaseDownloadLink?.absoluteString
        if let rangeOfHTTPS = urlString?.range(of: "https://") {
            urlString?.removeSubrange(rangeOfHTTPS)
        }
        guard var safeString = urlString else {
            return
        }
        safeString = "https://www.twitter.com/card?"+safeString
        log.info("encoded link: \(safeString)")

        let data = safeString.data(using: String.Encoding.ascii)

        if let filter = CIFilter(name: "CIQRCodeGenerator") {
            filter.setValue(data, forKey: "inputMessage")
            let transform = CGAffineTransform(scaleX: 3, y: 3)

            if let output = filter.outputImage?.applying(transform) {
                let qrCode = UIImage(ciImage: output)

                //let rawImageRef: CGImage = qrCode.cgImage!

                let colorMasking: [CGFloat] = [222, 255, 222, 255, 222, 255]
                UIGraphicsBeginImageContext(qrCode.size)
                var rawImageRef: CGImage = CIContext.init(options: nil).createCGImage(output, from: output.extent)!
                let maskedImageRef = rawImageRef.copy(maskingColorComponents: colorMasking)
                UIGraphicsGetCurrentContext()?.translateBy(x: 0.0, y: qrCode.size.height)
                UIGraphicsGetCurrentContext()!.scaleBy(x: 1.0, y: -1.0)
                UIGraphicsGetCurrentContext()?.draw(maskedImageRef!, in: CGRect(x: 0, y: 0, width: qrCode.size.width, height: qrCode.size.height))
                let result = UIGraphicsGetImageFromCurrentImageContext()
                UIGraphicsEndImageContext()

                qrCodeView = UIImageView(image: result)
                self.backgroundImage.addSubview(qrCodeView!)
                qrCodeView!.frame = CGRect(x: 96, y: 125, width: 180, height: 180)
            }
        }
    }

Any help would be much appreciated. Thanks so much in advance!

Cheers, Theo

2
  • I once attempted this and was unable to find a way to round the squares. Commented Jul 2, 2017 at 13:45
  • @JonRose it seems that twitter has done it natively in their app because they do not list that they use an API for it... must be a way, right? Commented Jul 2, 2017 at 14:14

1 Answer 1

3

I have part of a solution. I'll explain what I have so you can more forward with it. I believe that using CIFilter is a dead end since it only gives you the final image and then you have to go back to deconstruct it and modify it. For simple changes like color this is easy, but changing every box to look like something else is very hard.

So instead of using CIFilter you can use an open source library that get the actual bitmap of what a QR code should look like. If you look at QR code libraries for IOS most of them use CIFilter - which is not what we want. I found https://github.com/moqod/ios-qr-code-encoder that actually uses a library that really generates the QR code data.

I was able to modify it to draw an image for my choice for every box (instead of a box) and was able to get a VERY good result. When I get a chance I'll upload the code change, but honestly it was not that hard and anyone should be able to do it.

As far as doing it in swift I don't think that is a huge issue. There are known ways to bridge objective-c code to swift so it should be do-able.

Sign up to request clarification or add additional context in comments.

1 Comment

awesome thanks so much. ill check this out and get back to you if it works.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.