123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190 |
- using System;
- using System.Collections;
- using EZXR.Glass.SixDof;
- using System.Runtime.InteropServices;
- using UnityEngine;
- using Wheels.Unity;
- using EZXR.Glass.Device;
- using EZXR.Glass.Core;
- namespace EZXR.Glass.QRScanner
- {
- public class ScannerHandler : MonoBehaviour
- {
- public GameObject scanningView;
- public GameObject successView;
- public GameObject failedView;
- private byte[] imageBuffer;
- private int[] imageBufferClamp;
- private NormalRGBCameraDevice rgbCameraDevice;
- private EZVIOInputImage camImageBuffer;
- private Action startListeners;
- private Action<bool, string> completeListeners;
- private ZXing.BarcodeReader barcodeReader;
- private bool isCameraOpen = false;
- private bool isScannerStarted = false;
- private bool isScannnerComplete = false;
- private string qrCodeContent;
- private Coroutine timerCoroutine;
- private void Awake()
- {
- // ZeroDof
- transform.ActAsChild(HMDPoseTracker.Instance.Head);
- }
- private void OnEnable()
- {
- scanningView.SetActive(true);
- successView.SetActive(false);
- failedView.SetActive(false);
- qrCodeContent = string.Empty;
- StartCoroutine(startRGBCamera());
- timerCoroutine = StartCoroutine(startScannerTimer());
- }
- private void OnDisable()
- {
- Debug.Log($"-- ScannerHandler --, Scannner Complete: {qrCodeContent}");
- var isScanned = !string.IsNullOrEmpty(qrCodeContent);
- completeListeners?.Invoke(isScanned, qrCodeContent);
- if (timerCoroutine != null)
- {
- StopCoroutine(timerCoroutine);
- timerCoroutine = null;
- }
- stopRGBCamera();
- isScannerStarted = false;
- isScannnerComplete = false;
- }
- private void Update()
- {
- if (!isScannnerComplete && UpdateRGBCamera())
- {
- if (!isScannerStarted)
- {
- isScannerStarted = true;
- startListeners?.Invoke();
- }
- if (DecodeYUVImage(out var something))
- {
- isScannnerComplete = true;
- qrCodeContent = something;
- StartCoroutine(DelayAndDisable(1f));
- scanningView.SetActive(false);
- successView.SetActive(true);
- gameObject.GetComponent<AudioSource>().Play();
- if (timerCoroutine != null)
- {
- StopCoroutine(timerCoroutine);
- timerCoroutine = null;
- }
- }
- }
- }
- private IEnumerator startRGBCamera()
- {
- yield return new WaitUntil(() => SessionManager.Instance != null && SessionManager.Instance.IsInited);
- Debug.Log("-- ScannerHandler --, startRGBCamera");
- camImageBuffer = new EZVIOInputImage();
- rgbCameraDevice = new NormalRGBCameraDevice();
- rgbCameraDevice.Open();
- isCameraOpen = true;
- }
- private void stopRGBCamera()
- {
- Debug.Log("-- ScannerHandler --, stopRGBCamera");
- rgbCameraDevice?.Close();
- isCameraOpen = false;
- if (camImageBuffer.fullImg != IntPtr.Zero)
- {
- Marshal.FreeHGlobal(camImageBuffer.fullImg);
- camImageBuffer.fullImg = IntPtr.Zero;
- }
- if (imageBuffer != null)
- imageBuffer = null;
- if (imageBufferClamp != null)
- imageBufferClamp = null;
- }
- public void SetupListeners(Action onStart, Action<bool, string> onComplete)
- {
- startListeners = onStart;
- completeListeners = onComplete;
- }
- private bool UpdateRGBCamera()
- {
- if (ARFrame.SessionStatus != EZVIOState.EZVIOCameraState_Tracking)
- return false;
- if (!isCameraOpen || rgbCameraDevice == null)
- return false;
- return rgbCameraDevice.getCurrentImage(ref camImageBuffer, new float[8]);
- }
- private bool DecodeYUVImage(out string something)
- {
- something = string.Empty;
- if (camImageBuffer.imgFormat != EZVIOImageFormat.EZVIOImageFormat_YUV420A)
- {
- Debug.LogError($"-- ScannerHandler --, incompatible image format({camImageBuffer.imgFormat}) when decode.");
- return false;
- }
- int width = (int)camImageBuffer.imgRes.width;
- int height = (int)camImageBuffer.imgRes.height;
- int channelSize = width * height/* * 3 / 2*/;
- if (imageBuffer == null) imageBuffer = new byte[channelSize];
- Marshal.Copy(camImageBuffer.fullImg, imageBuffer, 0, channelSize); //只读Y通道
- // create a reader with a custom luminance source
- if (barcodeReader == null) barcodeReader = new ZXing.BarcodeReader { AutoRotate = false, Options = new ZXing.Common.DecodingOptions { TryHarder = false } };
- var result = barcodeReader.Decode(new ZXing.PlanarYUVLuminanceSource(imageBuffer, width, height, 0, 0, width, height, false));
- if (result != null && !string.IsNullOrEmpty(result.Text))
- {
- something = result.Text;
- return true;
- }
- return false;
- }
- private IEnumerator startScannerTimer()
- {
- yield return new WaitForSeconds(60f);
- scanningView.SetActive(false);
- failedView.SetActive(true);
- isScannnerComplete = true;
- yield return DelayAndDisable(1f);
- }
- private IEnumerator DelayAndDisable(float delay)
- {
- yield return new WaitForSeconds(delay);
- gameObject.SetActive(false);
- }
- }
- }
|