配置
目前大部分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运行无误后,在部署的过程中有地址冲突的问题;不过换了电脑重新生成后问题解决(有可能是那台电脑有点问题)。