Unity3d Ar Vuforia +zxing 实现二维码扫描

最近在写Ar项目,研究了一段时间Vuforia+zxing实现二维码扫描,走了许多弯路,浪费了不少时间,所以,分享一下代码,方便那些想要用vuforia+zxing来实现二维码扫描同窗。ui


直接贴代码:this

using UnityEngine;
using FairyGUI;


using ZXing;
using ZXing.Client.Result;
using Vuforia;

using System;

//扫描二维码
public class UIScanning : MonoBehaviour
{
    private GObject _ArVerifyQRUI_btn_back_name;
    private GComponent _mainView;
    private GLoader _mGloader;

    private GTextInput _ArVerifyQRUI_et_code_name;
    private Vuforia.Image.PIXEL_FORMAT m_PixelFormat = Vuforia.Image.PIXEL_FORMAT.RGB888;
    private bool m_RegisteredFormat = false;
    private bool m_LogInfo = true;


    public VuforiaBehaviour vuforia;


    public static event Action<ParsedResult, string> Scanned = delegate { };
    public static event Action<string> ScannedQRCode = delegate { };
    public static event Action<string> ScannedBarCode = delegate { };

    bool decoding;
    bool init;
    BarcodeReader barcodeReader = new BarcodeReader();


    void Awake()
    {
        UIPackage.AddPackage("fairyui_scan_main/scense_2/ArScanMain");
    }


    void Start()
    {
       
        Global.seleteScene(5);
        _mainView = this.GetComponent<UIPanel>().ui;
        _ArVerifyQRUI_btn_back_name = _mainView.GetChild("ArVerifyQRUI_btn_back_name");
        _ArVerifyQRUI_btn_back_name.visible = true;
        _ArVerifyQRUI_btn_back_name.onClick.Add(onClickBack);

        _mGloader = _mainView.GetChild("ArVerifyQRUI_Iimages").asLoader;
        _ArVerifyQRUI_et_code_name = _mainView.GetChild("ArVerifyQRUI_et_code_name").asTextInput;


        vuforia = GameObject.FindGameObjectsWithTag("ARScanningCamera")[0].GetComponent<VuforiaBehaviour>();

    }

    void Update()
    {
        if (vuforia == null)
            return;
        if (vuforia.enabled && !init)
        {
            //Wait 1/4 seconds for the device to initialize (otherwise it seems to crash sometimes)
            init = true;
            
            Loom.QueueOnMainThread(() =>
            {
                init = CameraDevice.Instance.SetFrameFormat(Vuforia.Image.PIXEL_FORMAT.RGB888, true);
            }, 0.25f);
        }
        if (vuforia.enabled && CameraDevice.Instance != null && !decoding)
        {
            var image = CameraDevice.Instance.GetCameraImage(Vuforia.Image.PIXEL_FORMAT.RGB888);
            if (image != null)
            {
                decoding = true;

                Loom.RunAsync(() =>
                {
                    try
                    {
                        var data = barcodeReader.Decode(image.Pixels, image.BufferWidth, image.BufferHeight, RGBLuminanceSource.BitmapFormat.RGB24);
                        if (data != null)
                        {
                            Loom.QueueOnMainThread(() =>
                            {
                                if (data.BarcodeFormat == BarcodeFormat.QR_CODE)
                                {
                                    ScannedQRCode(data.Text);
                                    if (_ArVerifyQRUI_et_code_name != null)
                                    {
                                        _ArVerifyQRUI_et_code_name.text = data.Text;
                                        
                                    }
                                }
                                if (data.BarcodeFormat != BarcodeFormat.QR_CODE)
                                {
                                    ScannedBarCode(data.Text);
                                    if (_ArVerifyQRUI_et_code_name != null)
                                    {
                                        _ArVerifyQRUI_et_code_name.text = data.Text;

                                    }

                                }
                               // var parsedResult = ResultParser.parseResult(data);
                               // if (target != null)
                               // {
                               //     target.SendMessage("Scanned", parsedResult, SendMessageOptions.DontRequireReceiver);
                                //}
                               // Scanned(parsedResult, data.Text);
                            });
                        }
                    }
                    finally
                    {
                        decoding = false;
                    }
                });
            }
        }
    }


    //返回按钮
    private void onClickBack()
    {
        Application.LoadLevel(Global.sceneHome);

    }





   

}


Loom 线程队列管理:线程

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System;
using System.Threading;
using System.Linq;

//Loom handles threading
public class Loom : MonoBehaviour
{
    private static Loom _current;

    public static Loom Current
    {
        get
        {
            if (_current == null && Application.isPlaying)
            {

                var g = GameObject.Find("Loom");
                if (g == null)
                {
                    g = new GameObject("Loom");
                }

                _current = g.GetComponent<Loom>() ?? g.AddComponent<Loom>();
            }

            return _current;
        }
    }

    void Awake()
    {
        if (_current != null && _current != this)
        {
            Destroy(gameObject);
        }
        else
        {
            _current = this;
        }
    }

    private List<Action> _actions = new List<Action>();
    public class DelayedQueueItem
    {
        public float time;
        public Action action;
        public string name;
    }
    private List<DelayedQueueItem> _delayed = new List<DelayedQueueItem>();

    public static void QueueOnMainThread(Action action, float time, string name)
    {
        lock (Current._delayed)
        {
            if (Current._delayed.Any(d => d.name == name))
                return;
            QueueOnMainThread(action, time);
        }
    }

    public static void QueueOnMainThread(Action action, string name)
    {
        QueueOnMainThread(action, 0, name);
    }

    public static void QueueOnMainThread(Action action, float time)
    {
        if (time != 0)
        {
            lock (Current._delayed)
            {
                Current._delayed.Add(new DelayedQueueItem { time = Time.time + time, action = action });
            }
        }
        else
        {
            lock (Current._actions)
            {
                Current._actions.Add(action);
            }
        }
    }

    public static void QueueOnMainThread(Action action)
    {
        lock (Current._actions)
        {
            Current._actions.Add(action);
        }
    }

    public static void RunAsync(Action a)
    {
        var t = new Thread(RunAction);
        t.Priority = System.Threading.ThreadPriority.Normal;
        t.Start(a);
    }

    private static void RunAction(object action)
    {
        ((Action)action)();
    }


    List<Action> toBeRun = new List<Action>();
    List<DelayedQueueItem> toBeDelayed = new List<DelayedQueueItem>();

    void Update()
    {
        //Process the non-delayed actions
        lock (_actions)
        {
            toBeRun.AddRange(_actions);
            _actions.Clear();
        }
        foreach (var a in toBeRun)
        {
            try
            {
                a();
            }
            catch (Exception e)
            {
                Debug.LogError("Queued Exception: " + e.ToString());
            }
        }
        toBeRun.Clear();
        lock (_delayed)
        {
            toBeDelayed.AddRange(_delayed);
        }
        foreach (var delayed in toBeDelayed.Where(d => d.time <= Time.time))
        {
            lock (_delayed)
            {
                _delayed.Remove(delayed);
            }
            try
            {
                delayed.action();
            }
            catch (Exception e)
            {
                Debug.LogError("Delayed Exception:" + e.ToString());
            }
        }
        toBeDelayed.Clear();

    }
}