在unity里做扫二维码的功能,虽然有插件,但是移动端UI一般不能自定义,所以后来自已做了一个,直接在c#层扫描解析,UI上就可以自己发挥了。
上代码:
这个是调用zxing的脚本。
using UnityEngine; using System.Collections; using ZXing; using ZXing.QrCode; public class QR { /// <summary> /// 解析二维码 /// </summary> /// <param name="tex"></param> /// <returns></returns> public static string Decode(Texture2D tex) { return DecodeColData(tex.GetPixels32(), tex.width, tex.height); //通过reader解码 } public static string DecodeColData(Color32[] data, int w, int h) { BarcodeReader reader = new BarcodeReader(); Result result = reader.Decode(data, w, h); //通过reader解码 //GC.Collect(); if (result == null) return ""; else { return result.Text; } } /// <summary> /// 生成二维码 /// </summary> /// <param name="content"></param> /// <param name="len"></param> /// <returns></returns> public static Texture2D GetQRTexture(string content, int len = 256) { var bw = new BarcodeWriter(); bw.Format = BarcodeFormat.QR_CODE; bw.Options = new ZXing.Common.EncodingOptions() { Height = len, Width = len }; var cols = bw.Write(content); Texture2D t = new Texture2D(len, len); t.SetPixels32(cols); t.Apply(); return t; } }
然后是封装:
using UnityEngine; using System.Collections; using System; using UnityEngine.UI; using System.Timers; /// <summary> /// 二维码解析工具 /// 关键函数: /// public static QRHelper GetInst() --得到单例 /// public event Action<string> OnQRScanned; --扫描回调 /// public void StartCamera(int index) --启动摄像头 /// public void StopCamera() --停止摄像头 /// public void SetToUI(RawImage raw,int UILayoutW,int UILayoutH) --把摄像机画面设置到一个rawimage上并使它全屏显示 /// </summary> public class QRHelper { public event Action<string> OnQRScanned; private static QRHelper _inst; public static QRHelper GetInst() { if (_inst == null) { _inst = new QRHelper(); } return _inst; } private int reqW = 640; private int reqH = 480; private WebCamTexture webcam; Timer timer_in, timer_out; /// <summary> /// 启动摄像头 /// </summary> /// <param name="index">手机后置为0,前置为1</param> public void StartCamera(int index) { StopCamera(); lock (mutex) { buffer = null; tbuffer = null; } var dev = WebCamTexture.devices; webcam = new WebCamTexture(dev[index].name); webcam.requestedWidth = reqW; webcam.requestedHeight = reqH; webcam.Play(); stopAnalysis = false; InitTimer(); timer_in.Start(); timer_out.Start(); } /// <summary> /// 停止 /// </summary> public void StopCamera() { if (webcam!=null) { webcam.Stop(); UnityEngine.Object.Destroy(webcam); Resources.UnloadUnusedAssets(); webcam = null; stopAnalysis = true; timer_in.Stop(); timer_out.Start(); timer_in = null; timer_out = null; } } /// <summary> /// 把摄像机画面设置到一个rawimage上并使它全屏显示 /// </summary> /// <param name="raw">rawimage</param> /// <param name="UILayoutW">UI布局时的宽度</param> /// <param name="UILayoutH">UI布局时的高度</param> public void SetToUI(RawImage raw,int UILayoutW,int UILayoutH){ raw.GetComponent<RectTransform>().sizeDelta = GetWH(UILayoutW,UILayoutH); int d = -1; if (webcam.videoVerticallyMirrored) { d = 1; } raw.GetComponent<RectTransform>().localRotation *= Quaternion.AngleAxis(webcam.videoRotationAngle, Vector3.back); float scaleY = webcam.videoVerticallyMirrored ? -1.0f : 1.0f; raw.transform.localScale = new Vector3(1, scaleY * 1, 0.0f); raw.texture = webcam; raw.color = Color.white; } //在考虑可能旋转的情况下计算UI的宽高 private Vector2 GetWH(int UILayoutW, int UILayoutH) { int Angle = webcam.videoRotationAngle; Vector2 init = new Vector2(reqW, reqH); if ( Angle == 90 || Angle == 270 ) { var tar = init.ScaleToContain(new Vector2(UILayoutH,UILayoutW)); return tar; } else { var tar = init.ScaleToContain(new Vector2(UILayoutW, UILayoutH)); return tar; } } private void InitTimer() { timer_in = new Timer(500); timer_in.AutoReset = true; timer_in.Elapsed += (a,b) => { ThreadWrapper.Invoke(WriteDataBuffer); }; timer_out = new Timer(900); timer_out.AutoReset = true; timer_out.Elapsed += (a,b)=>{ <div>本文来源gaodai.ma#com搞##代!^码7网</div> Analysis(); }; } private Color32[] buffer = null; private Color32[] tbuffer = null; private object mutex = new object(); private bool stopAnalysis = false; int dw, dh; private void WriteDataBuffer() { lock (mutex) { if (buffer == null && webcam!=null) { buffer = webcam.GetPixels32(); dw = webcam.width; dh = webcam.height; } } } //解析二维码 private void Analysis() { if (!stopAnalysis) { lock (mutex) { tbuffer = buffer; buffer = null; } if (tbuffer == null) { ; } else { string str = QR.DecodeColData(tbuffer, dw, dh); tbuffer = null; if (!str.IsNullOrEmpty() && OnQRScanned != null) { ThreadWrapper.Invoke(() => { if (OnQRScanned!=null) OnQRScanned(str); }); } } } tbuffer = null; } }