Building Multiple QR Codes Scanner Using Swing AVFoundation

Darwin Harianto
4 min readFeb 28, 2019

--

Hello everyone, at this day and age almost everybody will sacrifice anything for convenience, won't we?

At least, that's true for me. I would not revert back to using post mail for sending messages, at the time where smartphone is a thing. Every day our lives have become more and more convenient. People are also makes new things to make everything become more convenient.

Every once in a while, I would go to places and spot some flyer with QR Codes that are being attached at shop's wall. Then it struck me, can I scan multiple QR Codes at once? or should I scan it one by one? Well, I love convenient things, so I googled how to scan multiple QR Code at once. I searched it, but to no avail, I didn't find any example to do it. They usually have to install some kind of library. So I tried to built it myself using swift.

Luckily, QR Codes are readable for swift. So, I tried to use it to take a picture of 30 QR Codes and I want it to decipher it for me.

Contains number from 1 to 30

This is what I got.

Scanned around 16 QR codes

Not so bad, but it can only read about half of what I need. From the picture we can see that iOS prioritize the middle and then the outer parts. This result doesn't achieve what I want, so I need to make some adjustment here and there to make it more refined.

Then I realized, what if I rescanned the result while keeping the last scanned picture, maybe I might be able to get what I want. So I tried to do that, and here is the result.

Full scan result

And yes, this is perfect.

So, how did I do that?

Here's the step.

  1. Have Xcode installed
  2. Be familiar with AVFoundation and UIKit
  3. Have a real iPhone to take pictures

First, we need to make a new swift file and call it QRCodeScanFromImage.swift. We need to import AVFoundation and UIKit

So, what we need to get from this new file? we only need 2 things.

  1. The result of image
  2. The permission from user

This is how it will looks like

Inside the class you can write like this

Phew, this is a long code.

This will take care camera setup and configuration. I got this code from somewhere from the internet, if you are reading this, thanks for sharing.

at func photoOutput we can get the image from camera. From that point on, we start processing the image.

If I take the whole picture and search for QR Code, it will take quite a bit of time. This is quite a problem when I start doing my little project. My approach is to divide the picture to some equal parts and search for QR Code based on that parts. You can put this under func photoOutput.

This way, I divide the image to 8, 4, 2, and 1 part. Scan each of them separately. As soon as I locate a QR Code, I take that QR Code size and the image for the next step.

This code below will scan the position of QR Code and paint out those scanned QR Code position.

What I did with that code above is from the original image, I will crop a size of 2x QR Code size, then repeatedly scan from top left to bottom right. that's why there is a loop for row and column. For painting out, I am using UIBezierPath.

We have to rotate taken image from camera because iOS automatically rotate our taken image when we display it at our UIImageView.

At last, everything is all set. All that's left is for our ViewController.

For our View Controller we just need to setup our ImageView, UIView, and a button to take a picture.

This is how it looks like.

For our ViewController class

From what we can see, we only need to call 2 things when it start. Setup and check for availability.

Then an an action when we take a picture.

Last but not least, we need to take our data. We can do this by using the protocol we have made.

Now, you just need to build and run this on your phone.

Drawbacks

From this method, we can scan multiple images, but this have a huge drawbacks. This method can not scan multiple QR Codes with a huge difference in size. The other drawback is the speed. This have to scan multiple times to get what I need. Even if QR Code is only one, it will firstly divide it as 8 equal parts. So if you have any other solution, feel free to give me feedback about this.

For full working code, you can go to this link

--

--