国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > C# > 正文

Unity實現多平臺二維碼掃描

2020-01-24 00:02:16
字體:
來源:轉載
供稿:網友

在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里就可以了。

以上代碼5.1.2測試可用。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持武林網。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 阳东县| 余庆县| 临江市| 石渠县| 舟山市| 云梦县| 张家界市| 乡城县| 孝义市| 滦平县| 公主岭市| 宁安市| 陵水| 额济纳旗| 柳河县| 江达县| 云龙县| 罗甸县| 凤台县| 屏山县| 搜索| 瑞金市| 广东省| 共和县| 政和县| 阳西县| 慈利县| 贵州省| 清镇市| 大关县| 林周县| 平果县| 五常市| 卢氏县| 东山县| 云霄县| 德保县| 宣化县| 招远市| 金寨县| 临安市|