使用Unity扫描场景内的二维码,使用插件ZXing

时间:2024-04-23 10:23:26

使用Unity扫描场景内的二维码,使用插件ZXing

使用Unity扫描场景内的二维码,ZXing可能没有提供场景内扫描的方法,只有调用真实摄像机扫描二维码的方法。
实现的原理是:在摄像机上添加脚本,发射射线,当射线打到rawimage的时候获取rawimage的texture并作为二维码扫描。
支持webgl,windows。

代码

生成二维码,需要有zxing.unity.dll

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

/// <summary>
/// 生成二维码
/// </summary>
public class GenerateQRCode : MonoBehaviour
{
    public RawImage rawImage;

    void Start()
    {
        //整数倍变化256*N
        rawImage.texture = GenerateQRImageWithColor("hello word!", 256 * 3, Color.black);
    }


    /// <summary>
    /// 生成二维码 
    /// </summary>
    /// <param name="content">二维码内容</param>
    /// <param name="widthAndTall">宽度高度和宽度</param>
    /// <param name="color">二维码颜色</param>
    public Texture2D GenerateQRImageWithColor(string content, int widthAndTall, Color color)
    {
        BitMatrix bitMatrix;
        Texture2D texture = GenerateQRImageWithColor(content, widthAndTall, widthAndTall, color, out bitMatrix);
        return texture;
    }

    /// <summary>
    /// 生成2维码 方法二
    /// 经测试:能生成任意尺寸的正方形
    /// </summary>
    /// <param name="content"></param>
    /// <param name="width"></param>
    /// <param name="height"></param>
    Texture2D GenerateQRImageWithColor(string content, int width, int height, Color color, out BitMatrix bitMatrix)
    {
        // 编码成color32
        MultiFormatWriter writer = new MultiFormatWriter();
        Dictionary<EncodeHintType, object> hints = new Dictionary<EncodeHintType, object>();
        //设置字符串转换格式,确保字符串信息保持正确
        hints.Add(EncodeHintType.CHARACTER_SET, "UTF-8");
        // 设置二维码边缘留白宽度(值越大留白宽度大,二维码就减小)
        hints.Add(EncodeHintType.MARGIN, 1);
        hints.Add(EncodeHintType.ERROR_CORRECTION, ZXing.QrCode.Internal.ErrorCorrectionLevel.M);
        //实例化字符串绘制二维码工具
        bitMatrix = writer.encode(content, BarcodeFormat.QR_CODE, width, height, hints);

        // 转成texture2d
        int w = bitMatrix.Width;
        int h = bitMatrix.Height;
        print(string.Format("w={0},h={1}", w, h));
        Texture2D texture = new Texture2D(w, h);
        for (int x = 0; x < h; x++)
        {
            for (int y = 0; y < w; y++)
            {
                if (bitMatrix[x, y])
                {
                    texture.SetPixel(y, x, color);
                }
                else
                {
                    texture.SetPixel(y, x, Color.white);
                }
            }
        }

        texture.Apply();
        return texture;
    }

    /// <summary>
    /// 生成2维码 方法三
    /// 在方法二的基础上,添加小图标
    /// </summary>
    /// <param name="content"></param>
    /// <param name="width"></param>
    /// <param name="height"></param>
    /// <returns></returns>
    Texture2D GenerateQRImageWithColorAndIcon(string content, int width, int height, Color color, Texture2D centerIcon)
    {
        BitMatrix bitMatrix;
        Texture2D texture = GenerateQRImageWithColor(content, width, height, color, out bitMatrix);
        int w = bitMatrix.Width;
        int h = bitMatrix.Height;

        // 添加小图
        int halfWidth = texture.width / 2;
        int halfHeight = texture.height / 2;
        int halfWidthOfIcon = centerIcon.width / 2;
        int halfHeightOfIcon = centerIcon.height / 2;
        int centerOffsetX = 0;
        int centerOffsetY = 0;
        for (int x = 0; x < h; x++)
        {
            for (int y = 0; y < w; y++)
            {
                centerOffsetX = x - halfWidth;
                centerOffsetY = y - halfHeight;
                if (Mathf.Abs(centerOffsetX) <= halfWidthOfIcon && Mathf.Abs(centerOffsetY) <= halfHeightOfIcon)
                {
                    texture.SetPixel(x, y,
                        centerIcon.GetPixel(centerOffsetX + halfWidthOfIcon, centerOffsetY + halfHeightOfIcon));
                }
            }
        }

        texture.Apply();

        // 存储成文件
        byte[] bytes = texture.EncodeToPNG();
        string path = System.IO.Path.Combine(Application.dataPath, "qr.png");
        System.IO.File.WriteAllBytes(path, bytes);

        return texture;
    }
}

扫描二维码

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
using ZXing;

/// <summary>
/// 扫描二维码
/// </summary>
public class ScanQRCode : MonoBehaviour
{
    public Camera customCamera;
    public UnityEngine.UI.Text showText;
    public UnityEngine.UI.Button btnStartScan;

    public LayerMask layerMask; // 需要检测的图层
    public float rayLength = 5f; // 射线长度

    void Start()
    {
        btnStartScan.onClick.AddListener(OnStartScamOnClick);

    }

    private void OnStartScamOnClick()
    {
        // 发射一条射线从指定摄像机的屏幕中心
        Ray ray = customCamera.ScreenPointToRay(new Vector3(Screen.width / 2, Screen.height / 2, 0));

        // 使用 EventSystem 进行 UI 射线检测
        PointerEventData pointerEventData = new PointerEventData(EventSystem.current);
        pointerEventData.position = new Vector2(Screen.width / 2, Screen.height / 2);
        List<RaycastResult> results = new RaycastResult[1].ToList();
        EventSystem.current.RaycastAll(pointerEventData, results);

        // 如果检测到了UI元素
        if (results.Count > 0)
        {
            // 返回UI元素的名称
            Debug.Log("Hit UI object: " + results[0].gameObject.name);
            string imgo = GetColorImage(results[0].gameObject);
            showText.text= imgo;
        }
        else
        {
            // 如果没有检测到UI元素,则进行3D场景中的射线检测
            RaycastHit hitInfo;
            if (Physics.Raycast(ray, out hitInfo, rayLength))
            {
                // 返回击中物体的名称
                Debug.Log("Hit object: " + hitInfo.collider.gameObject.name);
            }
        }

    }

    private string GetColorImage(GameObject go)
    {
        RawImage rawImage;
        if (!go.TryGetComponent<RawImage>(out rawImage))
        {
            return "";
        }
        Texture2D texture = rawImage.texture as Texture2D;

        try
        {
            // 创建二维码解码器
            IBarcodeReader barcodeReader = new BarcodeReader();
            // 解码纹理中的二维码
            Result result = barcodeReader.Decode(texture.GetPixels32(), texture.width, texture.height);
            // 返回解码结果
            return result != null ? result.Text : null;
        }
        catch (System.Exception ex)
        {
            showText.text = ("Error scanning QR code: " + ex.Message);

            Debug.LogError("Error scanning QR code: " + ex.Message);
            return null;
        }

    }


}


场景布置

在这里插入图片描述

下载

可以私信下载
https://download.****.net/download/GoodCooking/89208272