1. 程式人生 > >【Unity+Hololens開發】識別二維碼

【Unity+Hololens開發】識別二維碼

第一步:實現掃描二維碼的功能

關於Unity識別二維碼的教程,網上有很多教程,我目前看到的都是使用了ZXing.Net

1.ZXing.Net下載匯入:

ZXing.Net的下載地址:

解壓後找到裡面的unity資料夾,底下有3個檔案,如下:


把這三個檔案拖到unity裡面

2.實現二維碼識別:

這個藉助外掛很容易實現,網上有很多參考,Unity應用商店裡也有提供的QRCode原始碼,下面是參考的一個比較簡潔的寫法,在這裡對其稍作改動並加上註釋:

using UnityEngine;
using System.Collections;
using ZXing;
using UnityEngine.UI;

public class QRcode : MonoBehaviour
{
    /// <summary> 包含RGBA </summary>
    public Color32[] data;
    /// <summary> 判斷是否可以開始掃描 </summary>
    private bool isScan;
    /// <summary> canvas上的RawImage,顯示相機捕捉到的影象 </summary>
    public RawImage cameraTexture;
    /// <summary> canvas上的Text,顯示獲取的二維碼內部資訊 </summary>
    public Text QRcodeText;
    /// <summary> 相機捕捉到的影象 </summary>
    private WebCamTexture webCameraTexture;
    /// <summary> ZXing中的方法,可讀取二維碼中的內容 </summary>
    private BarcodeReader barcodeReader;
    /// <summary> 計時,0.5s掃描一次 </summary>
    private float timer = 0;

    /// <summary>
    /// 初始化
    /// </summary>
    /// <returns></returns>
    IEnumerator Start()
    {
        barcodeReader = new BarcodeReader();
        yield return Application.RequestUserAuthorization(UserAuthorization.WebCam);//請求授權使用攝像頭
        if (Application.HasUserAuthorization(UserAuthorization.WebCam))
        {
            WebCamDevice[] devices = WebCamTexture.devices;//獲取攝像頭裝置
            string devicename = devices[0].name;
            webCameraTexture = new WebCamTexture(devicename, 400, 300);//獲取攝像頭捕捉到的畫面
            cameraTexture.texture = webCameraTexture;
            webCameraTexture.Play();
            isScan = true;
        }

    }

    /// <summary>
    /// 迴圈掃描,0.5秒掃描一次
    /// </summary>
    void Update()
    {
        if (isScan)
        {
            timer += Time.deltaTime;

            if (timer > 0.5f) //0.5秒掃描一次
            {
                StartCoroutine(ScanQRcode());//掃描
                timer = 0;
            }
        }
    }

    IEnumerator ScanQRcode()
    {
        data = webCameraTexture.GetPixels32();//相機捕捉到的紋理
        DecodeQR(webCameraTexture.width, webCameraTexture.height);
        yield return 0;
    }

    /// <summary>
    /// 識別二維碼並顯示其中包含的文字、URL等資訊
    /// </summary>
    /// <param name="width">相機捕捉到的紋理的寬度</param>
    /// <param name="height">相機捕捉到的紋理的高度</param>
    private void DecodeQR(int width, int height)
    {
        var br = barcodeReader.Decode(data, width, height);
        if (br != null)
        {
            QRcodeText.text = br.Text;
        }

    }
}

把這段程式掛到 Main Camera 上,建立一個canvas,建立 RawImage 和 Text 並拖拽到指令碼上,其中Text是用於顯示二維碼內部資訊的,RawImage是用於顯示攝像頭捕捉到的畫面的。

然後測試一下,二維碼的功能到這裡就實現了,經測試在PC和Android平臺上都適用,接下來是匯出HoloLens的部分。

第二步:匯出到HoloLens平臺

匯出HoloLens的時候就不怎麼友好了,報了很多錯誤,問題出在ZXing:


在hololens論壇上找到了關於這個問題的討論:

下面這個網址提供了一種解決方案,使得匯出時不會報錯:

它的解決方法是:

把匯入的外掛按照如下方式放置:其中 

 要複製兩份,一份放在WSAPlayer資料夾下,另一份放在Plugins目錄下


放在WSAPlayer目錄下的  設定如下:


放在Plugins目錄下的  設定如下:


再匯出時不會報錯。

但是,當在HoloLens中檢視時,發現仍然無法識別二維碼!!!

查詢原因,原來HoloLens的相機根本就沒有開啟!

難道HoloLens的相機與PC和Android呼叫方法不同嗎?看到下面這篇文章,發現是因為沒有開啟相機能力

解決方法我直接截圖過來了如下:


現在可以用HoloLens識別出二維碼中的內容了!

可是我之前使用的是Main Camera,因此canvas中的內容無法跟著頭盔移動,接下來匯入HoloLensToolKit的包,換上HoloLens的相機,但是這個相機是倒著的,0.0沒查為什麼,簡單粗暴地把我的canvas也到倒過來了。。。

現在在HoloLens上除錯感覺好多了

最後把我簡陋的介面 =_=(以前只有一個 RawImage 和一個 Text)美化一下,順手借用了QRCode外掛裡面的圖片,變成了下面這個樣子:


當然,在Hololens裡面看的時候,文字就是正著的了,而且黑色的背景也會被過濾掉。。。

——————————————————————————————————————————————————————

裡面包含原始碼匯出後的部分(放在APP資料夾下),可以直接在Hololens上執行:


注意:如果想重新匯出,請先刪除裡面的App和UWP資料夾!!否則會出現奇怪的錯誤,每次匯出都會重新生成UWP