代码之家  ›  专栏  ›  技术社区  ›  Maxim

与ARKit和ZXing统一阅读二维码

  •  0
  • Maxim  · 技术社区  · 6 年前

    我正在尝试通过以下库读取二维码:

    • 中兴

    解释纹理不会返回ZXing分析的任何数据。

    这是我为此使用的以下代码:

    #if UNITY_IOS && !UNITY_EDITOR
        // Update is called once per frame
        // BETTER: InvokeRepeating
        void Update()
        {
            if (!done) {
                ARTextureHandles handles = arSession.GetARVideoTextureHandles();
                //ARTextureHandles handles = UnityARSessionNativeInterface.GetARSessionNativeInterface().GetARVideoTextureHandles();
                if (handles.IsNull())
                {
                    return;
                }
                if (handles.TextureY != System.IntPtr.Zero) {
                    ReadQRCode (handles.TextureY);
                }
            }
    
    }
    #endif
    
    private void ReadQRCode(System.IntPtr mtlTexPtr)
    {
        Debug.Log("---------------");
        Debug.Log("Scanning...");
    
        Resolution currentResolution = Screen.currentResolution;
    
        tex = (UnityEngine.Texture2D)GameObject.Find("Camera").GetComponent<UnityARVideo>().m_ClearMaterial.GetTexture("_textureCbCr");
    
        tex.UpdateExternalTexture(mtlTexPtr);
    
        try
        {
            if(barCodeReader == null) {
                Debug.Log("Could not find barcorereader");
            }
            if(tex == null) {
                Debug.Log("Could not find texture");
            }
    
            var data = barCodeReader.Decode(tex.GetPixels32(), currentResolution.width, currentResolution.height);
            if (data != null)
            {
                Debug.Log("QR: " + data.Text);
            }
            else
            {
                Debug.Log("NO QR: " + "No QR code detected !");
            }
        }
        catch (Exception e)
        {
            Debug.LogError("Error reading QR");
            Debug.LogError(e.Message);
        }
    }
    
    2 回复  |  直到 6 年前
        1
  •  2
  •   Maxim    6 年前

    这对我来说是一个很好的速度。

    public class FrameCapturer : MonoBehaviour {
    
        // Script Inputs
        public bool m_shouldCaptureOnNextFrame = false;
        public Color32[] m_lastCapturedColors;
    
        // Privates
        Texture2D m_centerPixTex;
    
        void Start()
        {
            Resolution currentResolution = Screen.currentResolution;
            m_centerPixTex = new Texture2D(currentResolution.width, currentResolution.height, TextureFormat.RGBA32, false);
        }
    
        void OnPostRender()
        {
    
            if (m_shouldCaptureOnNextFrame)
            {
                Resolution res = Screen.currentResolution;
                m_lastCapturedColors = GetRenderedColors();
                m_shouldCaptureOnNextFrame = false;
            }
        }
    
        // Helpers
        Color32[] GetRenderedColors()
        {
            Resolution currentResolution = Screen.currentResolution;
            m_centerPixTex.ReadPixels(new Rect(0, 0, currentResolution.width, currentResolution.height), 0, 0);
            m_centerPixTex.Apply();
    
            return m_centerPixTex.GetPixels32();
        }
    }
    

    public class QRCodeReader : MonoBehaviour
    {
        public Camera cam;
        private BarcodeReader barCodeReader;
    
        FrameCapturer m_pixelCapturer;
    
        // Use this for initialization
        void Start()
        {
            barCodeReader = new BarcodeReader();
            Resolution currentResolution = Screen.currentResolution;
            m_pixelCapturer = cam.GetComponent<FrameCapturer>();
        }
    
        void Update()
        {
    
            Resolution currentResolution = Screen.currentResolution;
    
            try
            {
                Color32[] framebuffer = m_pixelCapturer.m_lastCapturedColors;
                if (framebuffer.Length == 0)
                {
                    return;
                }
    
                var data = barCodeReader.Decode(framebuffer, currentResolution.width, currentResolution.height);
                if (data != null)
                {
                    // QRCode detected.
                    Debug.Log(data);
                    Debug.Log("QR: " + data.Text);
    
                    //OnQrCodeRead(new QrCodeReadEventArgs() { text = data.Text });
                }
    
            }
            catch (Exception e)
            {
                Debug.LogError("Error reading QR");
                Debug.LogError(e.Message);
            }
    
            // skip 1 frame each time 
            // solves GetPixels() blocks for ReadPixels() to complete
            // https://medium.com/google-developers/real-time-image-capture-in-unity-458de1364a4c
            m_pixelCapturer.m_shouldCaptureOnNextFrame = true;
    
        }
    }
    

    https://github.com/realityenhanced/ARKitExperiments/blob/master/Assets/Scripts/CaptureCenterPixel.cs

        2
  •  1
  •   Daveloper    6 年前

    我曾与ZXing和ARkit一起工作,但从未一起工作过。

    试图让某些东西起作用,至少给你一个可能的暗示。

    作为ARCameraManager的子级,添加另一个(附加到主AR摄影机)摄影机,并附加ARVideo脚本(删除音频侦听器、Flare层和Guillayer等内容),还添加以下脚本,该脚本仅用于检索渲染器:

    [RequireComponent(typeof(Camera))]
    public class WebcamFetcher : MonoBehaviour
    {
    private RenderTexture _vertical;
    private RenderTexture _horizontal;
    private Camera _camera;
    
    // Update is called once per frame
    public RenderTexture RenderTexture
    {
        get
        {
            var orientation = Screen.orientation;
            if (orientation == ScreenOrientation.Landscape || orientation == ScreenOrientation.LandscapeLeft || orientation == ScreenOrientation.LandscapeRight)
            {
                return _horizontal;
            }
            else
            {
                return _vertical;
            }
        }
    }
    
    // Use this for initialization
    void Start ()
    {
        _camera = GetComponent<Camera>();
        _horizontal = new RenderTexture(Screen.width, Screen.height, 24);
        _vertical = new RenderTexture(Screen.height, Screen.width, 24);
    }
    
    // Update is called once per frame
    void Update()
    {
        var orientation = Screen.orientation;
        if (orientation == ScreenOrientation.Landscape || orientation == ScreenOrientation.LandscapeLeft || orientation == ScreenOrientation.LandscapeRight)
        {
            _camera.targetTexture = _horizontal;
        }
        else
        {
            _camera.targetTexture = _vertical;
        }
    }
    

    然后使用脚本,例如:

    private string DecodeQR(Color32[] pixels, int width, int height)
    {
        try
        {
            IBarcodeReader barcodeReader = new BarcodeReader();
    
            // decode the current frame
            var result = barcodeReader.Decode(pixels, width, height);
    
            if (result != null)
            {
                return result.Text;
            }
        }
        catch (Exception ex) { Debug.LogError(ex.Message); }
        return null;
    }
    
    [SerializeField] Text QrDisplay; // A text field to display detected QRs to
    
    public void OnQrDetect() // a callback for a UI button
    {
        var texture = new Texture2D(_webcamFetcher.RenderTexture.width, _webcamFetcher.RenderTexture.height);
        RenderTexture.active = _webcamFetcher.RenderTexture;
        texture.ReadPixels(new Rect(Vector2.zero, new Vector2(_webcamFetcher.RenderTexture.width, _webcamFetcher.RenderTexture.height)), 0, 0);
    
        var qrText = DecodeQR(texture.GetPixels32(), _webcamFetcher.RenderTexture.width, _webcamFetcher.RenderTexture.height);
        if (qrText != null)
        {
            QrDisplay.text = qrText;
        }
    }
    

    为我工作。纹理检索可能不是最有效的。 但它是有效的->这是可能的。