111 lines
2.8 KiB
C#
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;
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|