Monday, September 17, 2012

How to Decode QR Codes using Unity3D for Android (Zxing + Vuforia)

Following my previous blog post, here is my solution to decode QR codes on Android using Zxing and Vuforia.

UPDATE: If you also need to decode barcodes as well, here is a great solution. I haven't tried it though, I don't need to deal with barcodes as for now. My friend refers me to that page. I was late several months and didn't realize the solution was already out there :D oh well.

Step 1: on the blank Unity project, import Vuforia packages, and the Zxing.dll (provided at the end of this post, along with the camera prefab and this full script). Then add the ARCamera prefab to the scene, then add a script to it. Let's say it is CameraImageAccess.cs or whatever name you like.

Step 2: in the script, add
then implement ITrackerEventHandler so that it will look like this
class CameraImageAccess : MonoBehaviour, ITrackerEventHandler
then define the implementation of  ITrackerEventHandler
 public void OnTrackablesUpdated () { try { if(!isFrameFormatSet) { isFrameFormatSet = CameraDevice.Instance.SetFrameFormat(Image.PIXEL_FORMAT.GRAYSCALE, true); } cameraFeed = CameraDevice.Instance.GetCameraImage(Image.PIXEL_FORMAT.GRAYSCALE); tempText = new QRCodeReader().decode(cameraFeed.Pixels, cameraFeed.BufferWidth, cameraFeed.BufferHeight).Text; } catch { // Fail to detect QR Code! } finally { if(!string.IsNullOrEmpty(tempText)) { qrText = tempText; } } }
OnTrackablesUpdated will be called by QCARBehaviour on every frame. So you could set a flag variable to determine whether you would need to decode QR or not, in this example we'll constantly try to decode QR.
I use Image.PIXEL_FORMAT.GRAYSCALE because we don't need colors to process QR codes.
tempText and qrText are just string variables to hold the decoded QR codes.
You could display qrText at OnGUI event or just use it as you need.

Finally, in the Start function, register this component to QCARBehaviour and initialize the camera
void Start () { QCARBehaviour qcarBehaviour = GetComponent(); if (qcarBehaviour) { qcarBehaviour.RegisterTrackerEventHandler(this); } isFrameFormatSet = CameraDevice.Instance.SetFrameFormat(Image.PIXEL_FORMAT.GRAYSCALE, true); InvokeRepeating("Autofocus", 1f, 2f); }
That's it, now we're done. Here is my Unity Package file containing the QRCamera prefab, the required scripts, and the Zxing.dll itself.
To use it, you just drag the QRCamera prefab to a blank/new scene. Then build it.

Final Notes:

  • This will only run on mobile devices (Android, and maybe IOS but I haven't test this on IOS, why? because I have no device/access to it, and I dislike Apple, so I won't ever buy Apple products). With that said, it will NOT run on Editor or any other platform, so don't forget to set the correct build target.
  • The zxing.dll used here is NOT the same dll file from my previous post. Now it receives byte[] parameter right from Vuforia as opposed to sbyte[] from Color32[] as in my previous post.
  • Lastly, the provided Unity Package here does not include all the Vuforia components, so you'll need to import them first yourself into your project.