Csharp/C#教程:Unity实现多平台二维码扫描分享

在unity里做扫二维码的功能,虽然有插件,但是移动端UI一般不能自定义,所以后来自已做了一个,直接在c#层扫描解析,UI上就可以自己发挥了。

上代码:

这个是调用zxing的脚本。

usingUnityEngine; usingSystem.Collections; usingZXing; usingZXing.QrCode; publicclassQR{ ///<summary> ///解析二维码 ///</summary> ///<paramname="tex"></param> ///<returns></returns> publicstaticstringDecode(Texture2Dtex){ returnDecodeColData(tex.GetPixels32(),tex.width,tex.height);//通过reader解码 } publicstaticstringDecodeColData(Color32[]data,intw,inth){ BarcodeReaderreader=newBarcodeReader(); Resultresult=reader.Decode(data,w,h);//通过reader解码 //GC.Collect(); if(result==null) return""; else{ returnresult.Text; } } ///<summary> ///生成二维码 ///</summary> ///<paramname="content"></param> ///<paramname="len"></param> ///<returns></returns> publicstaticTexture2DGetQRTexture(stringcontent,intlen=256){ varbw=newBarcodeWriter(); bw.Format=BarcodeFormat.QR_CODE; bw.Options=newZXing.Common.EncodingOptions(){ Height=len, Width=len }; varcols=bw.Write(content); Texture2Dt=newTexture2D(len,len); t.SetPixels32(cols); t.Apply(); returnt; } }

然后是封装:

usingUnityEngine; usingSystem.Collections; usingSystem; usingUnityEngine.UI; usingSystem.Timers; ///<summary> ///二维码解析工具 ///关键函数: ///publicstaticQRHelperGetInst()--得到单例 ///publiceventAction<string>OnQRScanned;--扫描回调 ///publicvoidStartCamera(intindex)--启动摄像头 ///publicvoidStopCamera()--停止摄像头 ///publicvoidSetToUI(RawImageraw,intUILayoutW,intUILayoutH)--把摄像机画面设置到一个rawimage上并使它全屏显示 ///</summary> publicclassQRHelper{ publiceventAction<string>OnQRScanned; privatestaticQRHelper_inst; publicstaticQRHelperGetInst(){ if(_inst==null){ _inst=newQRHelper(); } return_inst; } privateintreqW=640; privateintreqH=480; privateWebCamTexturewebcam; Timertimer_in,timer_out; ///<summary> ///启动摄像头 ///</summary> ///<paramname="index">手机后置为0,前置为1</param> publicvoidStartCamera(intindex){ StopCamera(); lock(mutex){ buffer=null; tbuffer=null; } vardev=WebCamTexture.devices; webcam=newWebCamTexture(dev[index].name); webcam.requestedWidth=reqW; webcam.requestedHeight=reqH; webcam.Play(); stopAnalysis=false; InitTimer(); timer_in.Start(); timer_out.Start(); } ///<summary> ///停止 ///</summary> publicvoidStopCamera(){ 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> ///<paramname="raw">rawimage</param> ///<paramname="UILayoutW">UI布局时的宽度</param> ///<paramname="UILayoutH">UI布局时的高度</param> publicvoidSetToUI(RawImageraw,intUILayoutW,intUILayoutH){ raw.GetComponent<RectTransform>().sizeDelta=GetWH(UILayoutW,UILayoutH); intd=-1; if(webcam.videoVerticallyMirrored){ d=1; } raw.GetComponent<RectTransform>().localRotation*=Quaternion.AngleAxis(webcam.videoRotationAngle,Vector3.back); floatscaleY=webcam.videoVerticallyMirrored?-1.0f:1.0f; raw.transform.localScale=newVector3(1,scaleY*1,0.0f); raw.texture=webcam; raw.color=Color.white; } //在考虑可能旋转的情况下计算UI的宽高 privateVector2GetWH(intUILayoutW,intUILayoutH){ intAngle=webcam.videoRotationAngle; Vector2init=newVector2(reqW,reqH); if(Angle==90||Angle==270){ vartar=init.ScaleToContain(newVector2(UILayoutH,UILayoutW)); returntar; } else{ vartar=init.ScaleToContain(newVector2(UILayoutW,UILayoutH)); returntar; } } privatevoidInitTimer(){ timer_in=newTimer(500); timer_in.AutoReset=true; timer_in.Elapsed+=(a,b)=>{ ThreadWrapper.Invoke(WriteDataBuffer); }; timer_out=newTimer(900); timer_out.AutoReset=true; timer_out.Elapsed+=(a,b)=>{ Analysis(); }; } privateColor32[]buffer=null; privateColor32[]tbuffer=null; privateobjectmutex=newobject(); privateboolstopAnalysis=false; intdw,dh; privatevoidWriteDataBuffer(){ lock(mutex){ if(buffer==null&&webcam!=null){ buffer=webcam.GetPixels32(); dw=webcam.width; dh=webcam.height; } } } //解析二维码 privatevoidAnalysis(){ if(!stopAnalysis){ lock(mutex){ tbuffer=buffer; buffer=null; } if(tbuffer==null){ ; } else{ stringstr=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以消除镜像:

usingUnityEngine; usingSystem.Collections; usingSystem.Collections.Generic; usingPureMVC.Patterns; usingPureMVC.Interfaces; ///<summary> ///扫描二维码界面逻辑 ///</summary> publicclassScanQRMediator:Mediator{ AudioProxyaudio; publicQRViewTarView{ get{ returnbase.ViewComponentasQRView; } } publicScanQRMediator() :base("ScanQRMediator"){ } stringNextView=""; boolisInitOver=false; intcameraDelay=1; publicoverridevoidOnRegister(){ 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=newVector3(1,-1,0); } isInitOver=true; }); UmengStatistics.PV(TarView); //暂停背景音乐 audio.SetBGActive(false); } publicoverridevoidOnRemove(){ base.OnRemove(); TarView.BtnBack.onClick.RemoveListener(BtnEscClick); if(NextView!="UnlockView"){ audio.SetBGActive(true); } NextView=""; isInitOver=false; } boolisEsc=false; voidBtnEscClick(){ 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{ stringorigin=TarView.LastArg.SGet<string>("origin"); if(origin=="ARView"){ ToARView(); } elseif(origin=="UserInfoView"){ ToUserInfoView(); } else{ ToARView(); } } }); } voidToARView(){ AppFacade.Inst.RemoveMediator(this.MediatorName); ViewMgr.GetInst().ShowView(TarView,"ARView",null); } voidToUserInfoView(){ AppFacade.Inst.RemoveMediator(this.MediatorName); ViewMgr.GetInst().ShowView(TarView,"UserInfoView",null); varv=ViewMgr.GetInst().PeekTop(); varvc=newUserInfoMediator(); vc.ViewComponent=v; AppFacade.Inst.RegisterMediator(vc); } intreg=0; voidRegQRCB(){ if(reg==0){ QRHelper.GetInst().OnQRScanned+=OnQRScanned; reg=1; } } voidRemoveQRCB(){ if(reg==1){ QRHelper.GetInst().OnQRScanned-=OnQRScanned; reg=0; } } boolisQRJump=false; voidOnQRScanned(stringqrStr){ 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(); #ifYX_DEBUG Debug.Log("qris:"+qrStr); Toast.ShowText(qrStr,1.5f); #endif ViewMgr.GetInst().ShowView(TarView,"UnlockView",HashtableEX.Construct("QRCode",qrStr,"origin",TarView.LastArg.SGet<string>("origin"))); varv=ViewMgr.GetInst().PeekTop(); varvc=newUnlockMediator(); vc.ViewComponent=v; AppFacade.Inst.RegisterMediator(vc); }); } }

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

上述就是C#学习教程:Unity实现多平台二维码扫描分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!

本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

ctvol管理联系方式QQ:251552304

本文章地址:https://www.ctvol.com/cdevelopment/908432.html

(0)
上一篇 2021年10月25日
下一篇 2021年10月25日

精彩推荐