close

可用於PC或Android平台

 

這篇會使用到截圖(Texture2D的ReadPixels方法),可以參考我的這篇文章認識一下這個方法的參數作用

 

產生QR Code的方法請看這篇

先來下載ZXing並解壓縮,將 zxing.unity.dll 放入專案內的任意位置(該dll為於 ZXing\unity\zxing.unity.dll )

或到官方Github下載最新版

 

 

在此我示範兩種方法:「第一種為『靜態掃描』(直接將圖片放到Scene上並顯示出來),第二種為『動態掃描』(開啟攝影機鏡頭來掃描)」

P.S.這篇文章會使用到StartCoroutine和yield return這兩個方法和關鍵字,這兩個的意思可以看這篇文章

 

第一種、靜態掃描

 

 

開啟一個新的Unity專案,從 GameObject → 2D Object → Sprite 新增一個Sprite

 

然後將這個QR Code放入專案內(命名為Hello,該QR Code內容為"Hello World")

 

到Unity內,點選該圖片檔案,然後在Inspector將紅色框選的地方改為 Sprite(2D and UI) 後,按下Apply

 

 

之後點選剛剛新增的 New Sprite,將Hello檔案拖曳到Sprite欄位內

 

都完成後看到的Game就像這樣

 

 

 

開始編寫程式碼!

新增一個C# script,命名為QRCode


using UnityEngine;
using System.Collections;
using ZXing;
using ZXing.QrCode;

public class QRCode : MonoBehaviour
{
    void Start ()
    {
        StartCoroutine(scan());
    }

    private IEnumerator scan()
    {

        Texture2D t2D = new Texture2D(Screen.width, Screen.height);//掃描後的影片儲存大小,越大會造成效能消耗越大
        yield return new WaitForEndOfFrame();//等待Game影像繪製完畢
        BarcodeReader reader = new BarcodeReader();//ZXing的解碼物件
        t2D.ReadPixels(new Rect(0, 0, Screen.width, Screen.height), 0, 0, false);//掃描的範圍,設定為整個Game影像。
        t2D.Apply();//開始掃描
        Result res = reader.Decode(t2D.GetPixels32(), t2D.width, t2D.height);//選擇剛剛新增的圖片進行解碼,並將解碼後的資料回傳
        Debug.Log(res.Text);//將解碼後的資料列印出來
    }
}


 

將該腳本拖曳到任意物件上(我將其拖曳到Camera上,也可以拖曳到New Sprite上)後,按下執行!

 

 

 

第二種、動態掃描

 

開啟新專案,只留下Camera

 

新增一個C# script,命名為scan_QRCode

 

開始編寫程式碼!


 

using UnityEngine;
using System.Collections;
using ZXing;

public class scan_QRCode : MonoBehaviour
{
    private WebCamTexture myCam;//接收攝影機返回的圖片數據
    private BarcodeReader reader = new BarcodeReader();//ZXing的解碼
    private Result res;//儲存掃描後回傳的資訊
    private bool flag = true;//判斷掃描是否執行完畢
    
    void Start ()
    {
        StartCoroutine(open_Camera());//開啟攝影機鏡頭
    }

    void OnGUI()
    {
        if (myCam != null)//若有攝影機則將攝影機拍到的畫面畫出
        {
            if (myCam.isPlaying == true)//若攝影機已開啟
            {
                GUI.DrawTexture(new Rect(0, 0, Screen.width, Screen.height), myCam);//將攝影機讀取到的影像繪製到螢幕上
                if (flag == true)//若掃描已執行完畢,則再繼續進行掃描,防止第一個掃描還沒結束就又再次掃描,造成嚴重的記憶體耗盡
                {
                    StartCoroutine(scan());
                }
            }
        }
    }

    private IEnumerator open_Camera()
    {
        yield return Application.RequestUserAuthorization(UserAuthorization.WebCam);    //授權開啟鏡頭
        if (Application.HasUserAuthorization(UserAuthorization.WebCam))
        {
            //設置攝影機要攝影的區域
            myCam = new WebCamTexture(WebCamTexture.devices[0].name, Screen.width, Screen.height, 60);/* (攝影機名稱, 攝影機要拍到的寬度, 攝影機要拍到的高度, 攝影機的FPS) */
            myCam.Play();//開啟攝影機
        }
    }

    private IEnumerator scan()
    {
        flag = false;//掃描開始執行

        Texture2D t2D = new Texture2D(Screen.width, Screen.height);//掃描後的影像儲存大小,越大會造成效能消耗越大,若影像嚴重延遲,請降低儲存大小。
        yield return new WaitForEndOfFrame();//等待攝影機的影像繪製完畢

        t2D.ReadPixels(new Rect(0, 0, Screen.width, Screen.height), 0, 0, false);//掃描的範圍,設定為整個攝影機拍到的影像,若影像嚴重延遲,請降低掃描大小。
        t2D.Apply();//開始掃描
        
        res = reader.Decode(t2D.GetPixels32(), t2D.width, t2D.height);//對剛剛掃描到的影像進行解碼,並將解碼後的資料回傳
        
        //若是掃描不到訊息,則res為null
        if (res != null)
        {
            Debug.Log(res.Text);//將解碼後的資料列印出來
        }
        flag = true;//掃描完畢
    }

    void OnDisable()
    {
        //當程式關閉時會自動呼叫此方法關閉攝影機
        myCam.Stop();
    }
}


 

完成後將腳本拖曳到Camera上後,點選執行!

arrow
arrow
    全站熱搜

    Yang 發表在 痞客邦 留言(17) 人氣()