温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

Unity实现多平台二维码扫描的方法

发布时间:2021-04-12 12:59:13 来源:亿速云 阅读:282 作者:小新 栏目:编程语言

小编给大家分享一下Unity实现多平台二维码扫描的方法,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!

在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)=>{       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;   } }

调用方式如下,用了pureMVC,可能理解起来有点乱,也不能直接用于你的工程,主要看OnRegister和OnRemove里是怎么启动和停止的,以及RegQRCB、RemoveQRCB、OnQRSCcanned如何注册、移除以及响应扫描到二维码的事件的。在onregister中,由于ios上画面有镜象,所以把rawimage的scale的y置为了-1以消除镜像:

using UnityEngine; using System.Collections; using System.Collections.Generic; using PureMVC.Patterns; using PureMVC.Interfaces; /// <summary> /// 扫描二维码界面逻辑 /// </summary> public class ScanQRMediator : Mediator {     AudioProxy audio;  public QRView TarView {     get {       return base.ViewComponent as QRView;     }   }   public ScanQRMediator()     : base("ScanQRMediator") {   }   string NextView = "";   bool isInitOver = false;   int cameraDelay = 1;   public override void OnRegister() {     base.OnRegister();       if (Application.platform == RuntimePlatform.IPhonePlayer) {       cameraDelay = 5;     }     else {       cameraDelay = 15;     }       audio = AppFacade.Inst.RetrieveProxy<AudioProxy>("AudioProxy");       TarView.BtnBack.onClick.AddListener(BtnEscClick);          QRHelper.GetInst().StartCamera(0);     TarView.WebcamContent.rectTransform.localEulerAngles = Vector3.zero;     CoroutineWrapper.EXEF(cameraDelay, () => {       RegQRCB();       QRHelper.GetInst().SetToUI(TarView.WebcamContent, 1536, 2048);       if (Application.platform == RuntimePlatform.IPhonePlayer) {         TarView.WebcamContent.rectTransform.localScale = new Vector3(1, -1, 0);       }       isInitOver = true;     });     UmengStatistics.PV(TarView);     //暂停背景音乐     audio.SetBGActive(false);   }     public override void OnRemove() {     base.OnRemove();     TarView.BtnBack.onClick.RemoveListener(BtnEscClick);     if (NextView != "UnlockView") {       audio.SetBGActive(true);     }     NextView = "";     isInitOver = false;   }   bool isEsc = false;   void BtnEscClick() {     if (isEsc || !isInitOver) {       return;     }     isEsc = true;       TarView.WebcamContent.texture = null;     TarView.WebcamContent.color = Color.black;     RemoveQRCB();     QRHelper.GetInst().StopCamera();       CoroutineWrapper.EXEF(cameraDelay, () => {       isEsc = false;       if (Application.platform == RuntimePlatform.IPhonePlayer) {         ToUserInfoView();       }       else {         string origin = TarView.LastArg.SGet<string>("origin");         if (origin == "ARView") {           ToARView();         }         else if (origin == "UserInfoView") {           ToUserInfoView();         }         else {           ToARView();         }       }     });   }   void ToARView() {     AppFacade.Inst.RemoveMediator(this.MediatorName);     ViewMgr.GetInst().ShowView(TarView, "ARView", null);   }   void ToUserInfoView() {     AppFacade.Inst.RemoveMediator(this.MediatorName);     ViewMgr.GetInst().ShowView(TarView, "UserInfoView", null);     var v = ViewMgr.GetInst().PeekTop();     var vc = new UserInfoMediator();     vc.ViewComponent = v;     AppFacade.Inst.RegisterMediator(vc);   }   int reg = 0;   void RegQRCB() {     if (reg == 0) {       QRHelper.GetInst().OnQRScanned += OnQRScanned;       reg = 1;     }   }   void RemoveQRCB() {     if (reg == 1) {       QRHelper.GetInst().OnQRScanned -= OnQRScanned;       reg = 0;     }   }   bool isQRJump = false;   void OnQRScanned(string qrStr) {     if (isQRJump) {       return;     }     isQRJump = true;       TarView.WebcamContent.texture = null;     TarView.WebcamContent.color = Color.black;     RemoveQRCB();     QRHelper.GetInst().StopCamera();     NextView = "UnlockView";     CoroutineWrapper.EXEF(cameraDelay, () => {       isQRJump = false;       AppFacade.Inst.RemoveMediator(this.MediatorName);       audio.PlayScanedEffect(); #if YX_DEBUG       Debug.Log("qr is :"+qrStr);       Toast.ShowText(qrStr,1.5f); #endif       ViewMgr.GetInst().ShowView(TarView, "UnlockView", HashtableEX.Construct("QRCode", qrStr, "origin", TarView.LastArg.SGet<string>("origin")));       var v = ViewMgr.GetInst().PeekTop();       var vc = new UnlockMediator();       vc.ViewComponent = v;       AppFacade.Inst.RegisterMediator(vc);     });   } }

最后,放上zxing.unity.dll,放在plugins里就可以了。

以上是“Unity实现多平台二维码扫描的方法”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注亿速云行业资讯频道!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI