配置
目前大部分Hololens进行二维码识别的开发都是基于ZXing的包完成,首先需要完成zxing.unity.dll,很多地方应该都能下载,也可以直接上github上下载(下载点这里)。
下载时注意一下版本就好,过老的zxing兼容性可能存疑,我这边使用的是 0.16.8.0的版本。
直接在项目Assets下新建Plugins,将dll拖入文件。
配置的话,用默认的就可以(这里面最重要的是UMP的平台配置,不过不用管,默认就支持了)。
场景需求
场景中需要有一个UI Canvas,文档下面应该包含RawImage和Text两个组件,同时需要一个相机获取权限Main camera。
代码
代码的话我试了两段代码,应该都没问题。
方法一:
using UnityEngine;
using System.Collections;
using ZXing;
using UnityEngine.UI;public class qrB : 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>void Start(){barcodeReader = new BarcodeReader();//yield return Application.RequestUserAuthorization(UserAuthorization.WebCam);//请求授权使用摄像头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;}}}
方法二:
using System;
using System.Collections;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Events;
using UnityEngine.Serialization;
using ZXing;public class qrC : MonoBehaviour
{//相机捕捉到的图像private WebCamTexture webCameraTexture;//ZXing中的类,可读取二维码的内容private BarcodeReader barcodeReader;//计时,0.5s扫描一次private float scanInterval = 0.5f;//存放摄像头画面数据private Color32[] data;//显示摄像头画面public RawImage cameraTexture;//显示二维码信息public Text QRCodeText;//是否正在扫描private bool scaning;//定义未找到设备相机事件[Serializable]public class NoCameraErrorEvent : UnityEvent { }[FormerlySerializedAs("NoCameraError")][SerializeField]private NoCameraErrorEvent m_NoCameraError = new NoCameraErrorEvent();//定义扫码成功事件public Action<string> OnCompleted;//开始扫描二维码public void StartScanQRCode(){StartCoroutine(RequestWebCamAuthorization());}//请求相机权限IEnumerator RequestWebCamAuthorization(){barcodeReader = new BarcodeReader();yield return Application.RequestUserAuthorization(UserAuthorization.WebCam);//请求授权使用摄像头if (Application.HasUserAuthorization(UserAuthorization.WebCam)){WebCamDevice[] devices = WebCamTexture.devices;//获取摄像头设备if (devices.Length == 0){Debug.LogError("device no camera available");m_NoCameraError.Invoke();yield break;}string devicename = devices[0].name;webCameraTexture = new WebCamTexture(devicename, 400, 300);//获取摄像头捕捉到的画面if (cameraTexture != null){cameraTexture.enabled = true;cameraTexture.texture = webCameraTexture;}webCameraTexture.Play();StartCoroutine(ScanQRCode());}}//扫描二维码private IEnumerator ScanQRCode(){scaning = true;while (true){data = webCameraTexture.GetPixels32();//相机捕捉到的纹理DecodeQR(webCameraTexture.width, webCameraTexture.height);yield return new WaitForSeconds(scanInterval);if (!scaning)break;}}/// <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){//Debug.LogFormat("QR Code: {0}", br.Text);if (QRCodeText != null){QRCodeText.text = br.Text;Debug.Log(br.Text); //接口位置!}Stop();OnCompleted?.Invoke(br.Text);}else{if (QRCodeText != null)QRCodeText.text = "";}}//停止扫描public void Stop(){scaning = false;}private void Start(){StartScanQRCode();}private void Update(){ScanQRCode();}
}
经过测试,都可用。
效果
常见问题
问题一:注意启动Hololens的相机,project setting–> player --> Publishing Setting -->WebCam勾选。
问题二:我这边在unity运行无误后,在部署的过程中有地址冲突的问题;不过换了电脑重新生成后问题解决(有可能是那台电脑有点问题)。