使用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