Net.Like.Xue.Tokyo/Assets/BITKit/Unity/Scripts/UX/Library/QRVisualElement.cs

111 lines
2.8 KiB
C#

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UIElements;
using ZXing;
using ZXing.Common;
namespace BITKit.UX
{
public class QRVisualElement : VisualElement
{
public new class UxmlTraits:VisualElement.UxmlTraits
{
private readonly UxmlStringAttributeDescription m_TabsAttribute = new ()
{
name = "value"
};
public override void Init(VisualElement ve, IUxmlAttributes bag, CreationContext cc)
{
base.Init(ve, bag, cc);
var self = (QRVisualElement)ve;
self.Value = m_TabsAttribute.GetValueFromBag(bag, cc);
}
}
public new class UxmlFactory : UxmlFactory<QRVisualElement, UxmlTraits> { }
public QRVisualElement()
{
RegisterCallback<GeometryChangedEvent>(x =>
{
if (visible)
{
Rebuild();
}
});
}
public string Value
{
get => _value;
set
{
_value= value;
Rebuild();
}
}
private string _value;
private Texture _texture;
private void Rebuild()
{
if (float.IsNaN(layout.width) || float.IsNaN(layout.height))return;
if(layout.width <10 || layout.height <10)return;
var target = _value;
if (string.IsNullOrEmpty(_value))
{
target = nameof(QRVisualElement);
}
style.backgroundImage = GenerateQRImageWithColor(target, (int)layout.width, (int)layout.height, Color.black, out var bitMatrix);
Texture2D GenerateQRImageWithColor(string content, int width, int height, Color color, out BitMatrix bitMatrix)
{
width=height=Mathf.Max(width,height);
if (_texture)
{
Object.DestroyImmediate(_texture);
}
// 编码成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;
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();
//byte[] bytes = texture.EncodeToPNG();
//string path = System.IO.Path.Combine(Application.dataPath, "qr.png");
//System.IO.File.WriteAllBytes(path, bytes);
_texture = texture;
return texture;
}
}
}
}