ZXing Library with Unity

I’ve been trying to get the ZXing.Net unity library to work with Unity…with no success so far. No matter how many bar codes I’ve put up in front of my webcam it doesn’t return any results. Has anyone had any success getting these two to play along? this is my filthy work in progress below:

public class CodeScanner : MonoBehaviour {
  
    public WebCamTexture CamTexture;
    private Thread CodeScannerThread;
    public RawImage Image;

    private Color32[] c;
    private sbyte[] d;
    private int W, H, WxH;
    private int x, y, z;

    private string DecryptedData;

    public Quaternion baseRotation;
    private Rect screenRect;
  
    private bool isQuit;
  
    public string LastResult;
    private bool shouldEncodeNow;
    public Text DebugT;

    void OnEnable () {
        if(CamTexture != null) {
            CamTexture.Play();
            W = CamTexture.width;
            H = CamTexture.height;
            WxH = W * H;

        }
    }
  
    void OnDisable () {
        if(CamTexture != null) {
            CamTexture.Pause();
        }
    }
  
    void OnDestroy () {
        CodeScannerThread.Abort();
        CamTexture.Stop();
    }


  
    void Awake () {
        CamTexture = new WebCamTexture();
  
        c = null;
        OnEnable();

        Image.texture = CamTexture;

        //flip preview on iOS
        #if UNITY_IOS
        //Image.GetComponent<RectTransform>().localScale = new Vector3(1920f/1080f, -1080f/1920f, 0.0f);
        #endif
        baseRotation = transform.rotation;

        CodeScannerThread = new Thread(DecodeQR);
        CodeScannerThread.Start();
    }
  
    void Update () {
        //float scaleY = CamTexture.videoVerticallyMirrored ? -1 : 1;
        //Image.transform.localScale = new Vector3(W, scaleY * H, 0);

        //transform.rotation = baseRotation * Quaternion.AngleAxis(CamTexture.videoRotationAngle, Vector3.back);
        if(LastResult != null && LastResult.Trim().Length > 0)
        {
            DebugT.text = LastResult;
        }
        if (c == null)
        {
            Debug.Log ("Reading...");
            CamTexture.GetPixels32(c);
        }
    }

    void DecodeQR () {
        var barcodeReader = new ZXing.BarcodeReader();
        barcodeReader.AutoRotate = true;
        barcodeReader.TryInverted = true;
        barcodeReader.Options.TryHarder = true;
        while(true) {
            Debug.Log("Scanning...");
            try {


                if(c != null)
                {
                    Debug.Log("Decoding");
                    Result decode = barcodeReader.Decode(c,W,H);
                    if (decode != null)
                    {
                        Debug.Log ("NOT NULL!");
                        LastResult = decode.Text;
                        shouldEncodeNow = true;
                        print(decode.Text);
                    }
                }
                // Sleep a little bit and set the signal to get the next frame
                Thread.Sleep(200);
                //c = null;
            }
            catch(Exception e) {
                Debug.Log (e);
                continue;
            }
        }
    }
}

Found this call stack in xcode that might hint at why their are issues:

System.NullReferenceException: A null value was found where an object instance was required.

at UnityStandardAssets.CrossPlatformInput.TiltInput.OnDisable () [0x00000] in :0

at ZXing.PDF417.Internal.Detector.detect (Boolean multiple, ZXing.Common.BitMatrix bitMatrix) [0x00000] in :0

at ZXing.PDF417.Internal.Detector.detect (ZXing.BinaryBitmap image, IDictionary`2 hints, Boolean multiple) [0x00000] in :0

at ZXing.PDF417.PDF417Reader.decode (ZXing.BinaryBitmap image, IDictionary`2 hints, Boolean multiple) [0x00000] in :0

at ZXing.PDF417.PDF417Reader.decode (ZXing.BinaryBitmap image, IDictionary`2 hints) [0x00000] in :0

at DG.Tweening.Plugins.Core.PathCore.Path.Draw (DG.Tweening.Plugins.Core.PathCore.Path p) [0x00000] in :0

at ZXing.MultiFormatReader.decodeInternal (ZXing.BinaryBitmap image) [0x00000] in :0

OK, So I figured it out, the UnityEngine dll that they built with is too old. Download the source for ZXing.net, open the Unity project, change the reference to the UnityEngine.dll on your machine rebuild and use this DLL and everything works.

EDIT:

Spoke too soon, still getting the above error in XCODE for iOS but I at least have it working for PC

EDIT 2:

OK, you can get this to work in XCODE it appears, iOS’s WebCamTexture doesn’t immediately return its proper width and height, and instead reports 16 initially. I was creating too small of an array for the image data. Coincidently , if you give XZing a 16 by 16 image array it will just ignore it and break the code.

1 Like

You’re right, OS’s WebCamTexture doesn’t return its proper width and height and instead reports 16 and there is an active issue http://issuetracker.unity3d.com/issues/ios-webcamtexture-dot-width-slash-height-always-returns-16 about that.
Did you find a workaround?

Hi, guys, I have a similar issue, when I was running the Unity demo on iOS device, I got an exception like this :
Setting up 1 worker threads for Enlighten.

Thread → id: 5f77000 → priority: 1

Unhandled Exception: System.NullReferenceException: A null value was found where an object instance was required.

at ZXing.QrCode.Internal.FinderPatternFinder.find (IDictionary`2 hints) [0x00000] in :0

at ZXing.QrCode.Internal.Detector.detect (IDictionary`2 hints) [0x00000] in :0

at ZXing.QrCode.QRCodeReader.decode (ZXing.BinaryBitmap image, IDictionary`2 hints) [0x00000] in :0

at ZXing.MultiFormatReader.decodeInternal (ZXing.BinaryBitmap image) [0x00000] in :0

at ZXing.MultiFormatReader.decode (ZXing.BinaryBitmap image, IDictionary`2 hints) [0x00000] in :0

at ZXing.BarcodeReaderGeneric`1[T].Decode (ZXing.LuminanceSource luminanceSource) [0x00000] in :0

at ZXing.BarcodeReaderGeneric`1[T].Decode (.T rawRGB, Int32 width, Int32 height) [0x00000] in :0

at BarcodeCam.DecodeQR () [0x00000] in :0

at System.Threading.ThreadStart.Invoke () [0x00000] in :0

(Filename: /Users/builduser/buildslave/unity/build/artifacts/generated/common/runtime/UnityEngineDebugBindings.gen.cpp Line: 64)

then I updated my Unity3d to 5.2.3, but the error still there.

I have not tried IOS but it worked for me on android. Also went thorugh stackoverlfow post QR decode exceptions using ZXing.NET in Unity - Stack Overflow
for additional help. The code worked like charm. Thanks a lot guys.

If you want to detect barcodes on iOS and Android using the camera, don’t use ZXing. Use NatCam. It can read 8 different types of barcodes including QR, EAN_13, EAN_8, and much more.

Don’t use NatCam, NatCorder NatMic, they seem all good products but they are all expensive and buggy as hell

I agree. NatCam is a ripoff