Unity实用功能之扫描读取二维码

1,903 阅读4分钟

这是我参与8月更文挑战的第8天,活动详情查看:8月更文挑战

概述

上两篇文章主要介绍了两种不同的方法创建二维码,但是只会创建还不行,还要能读取解析二维码。识别二维码的方式有很多,有的是直接调用摄像机进行扫码,而有的是直接识别图片。其实归根结底第二种方法就是把扫描那一步给声省略掉了。接下来就让我们看一下。在Unity中是如何调取摄像头和识别二维码的。

准备工作

识别二维码这里面我们使用了ZXing.dll中的BarcodeReader的Decode。所以说不管用前面哪种方法差创建二维码,最终都是需要用到ZXing.dll(→_→)。二维码我们就使用上一篇文章创建的二维码。

思路分析

识别二维码,首先需要获取到二维码图片,分两种方式:

  1. 使用摄像头扫一扫
  2. 直接长按图片识别等 当我们获取到图片后,通过GetPixels32()获取Color32格式的像素颜色块。然后在通过Decode获取二维码中的内容

功能实现

Unity调取相机并显示在屏幕

在Unity中使用摄像机,需要用到WebCamTexture来获取摄像头数据,然后将获取到的数据赋值给UGUI的RawImage上,才能够将相机拍摄到的内容显示在屏幕中。接来下看一下如何获取相机
首先定义两个参数WebCamTexture和RawImage\

  • private WebCamTexture mWebCamTexture;
  • public RawImage rawImage; 接下来写创建摄像机方法。
    注意:创建摄像机的时候,要在方法中传入摄像机的名称,有的时候电脑连接多个摄像头还有手机有前后摄像头,所以我们需要明确要使用哪个摄像头
 /// <summary>
 /// 读取摄像机
 /// </summary>
 /// <param name="deviceName"></param>
 private void CreateWebcamTex(string deviceName)
 {
     mWebCamTexture = new WebCamTexture(deviceName, 1280, 720);
     rawImage.texture = mWebCamTexture;
     //开启摄像头
     mWebCamTexture.Play();
 }

接下来就是初始化相机方法,可以在程序运行就启动,也可以写到一个按钮的点击事件中等都可以

//调用摄像头
//获取所有摄像头
WebCamDevice[] devices = WebCamTexture.devices;
foreach (var item in devices)
{
    if (!item.isFrontFacing)
    {
        CreateWebcamTex(item.name);
        break;
    }
}

这样摄像头就成功的调起来了,就可以愉快的进行二维码的扫描了。

二维码识别

识别二维码时我们用到的是 Decode(T rawRGB, int width, int height);,我们是通过Texture2D的Color32[]来进行数据识别的,接下看一下实现方法(由于电脑没有摄像头,就直接识别创建好的二维码,而不是摄像头拍到的,其实都是一样的,就是图片的来源不同,一个是拍到的,一个是我们自己创建的)。

image.png

首先来看一下读取二维码数据

    //申请一个读取二维码的变量
    private BarcodeReader mReader = new BarcodeReader();

    public string Decode(Color32[] colors, int width, int height)
    {
        //将画面中的二维码信息检索出来
        var result = mReader.Decode(colors, width, height);
        
        if (result != null)
        {
            return result.Text;
        }
        return null;
    }

接下来就是调用此方法进行二维码识别,我们首先来看直接识别,不使用摄像头
直接识别我们可以直接调用此方法,将Color32[],和图片的宽高传入即可 首先获取Color32[]

//存储摄像头画面信息贴图转换的颜色数组
Color32[] m_colorData = (rawImage.texture as Texture2D).GetPixels32();

上述方法中,由于RawImage的图片属性是Texture,而GetPixels32方法是Texture2D,所以需要对图片进行下格式转换 紧接着就可以直接调用二维码读取方法了

string result = Decode(m_colorData, rawImage.texture.width, rawImage.texture.height);
if (!string.IsNullOrEmpty(result))
{          
    //识别成功后做相应操作
    Debug.Log("识别结果:" + result);
}        

摄像头识别方法
整体是被方法同上,就是多了一步摄像头识别,由于是摄像头扫描,所以我们要一直扫描,一两秒扫描一次即可,扫描成功之后将摄像机关闭即可
扫描方法如下:

    /// <summary>
    /// 扫描
    /// </summary>
    /// <returns></returns>
    private IEnumerator Scan()
    {
        yield return new WaitForSeconds(0.2F);
        yield return new WaitForEndOfFrame();
        if (mWebCamTexture != null && mWebCamTexture.width > 100)
        {
            //调用识别方法
            string result = Decode(mWebCamTexture.GetPixels32(), mWebCamTexture.width, mWebCamTexture.height);
            if (!string.IsNullOrEmpty(result))
            {
                mWebCamTexture.Stop();
                //识别成功后做相应操作
                Debug.Log("识别结果:" + result);
            }
            else
            {
                StartCoroutine(Scan());
            }
        }
    }

随后然我们来看一下扫描效果,案例为创建二维码,然后将二维码内容读取出来

展示2.gif

写在最后

本文中,调取摄像头方法在写文章时没有经过验证,因为电脑没有接摄像头,所以各位在使用调取摄像方法的时候注意看一下是否有问题,不过正常来说是不可能出错的(#^.^#)。
所有分享的内容均为作者在日常开发过程中使用过的各种小功能点,分享出来也变相的回顾一下,如有写的不好的地方还请多多指教。Demo源码会在之后整理好之后分享给大家。欢迎大家相互学习进步。