Read QR Code in Unity with ARKit and ZXing












0















I'm trying to read a QR code with the following libraries:




  • ARKit

  • ZXing


However it doesn't seem to go well. After several hours I still don't manage to read out a decent QR code.
When debugging i apply the texture to see my result. It looks red because of the Texture Y but other than that it shows the QR code.
Interpreting the texture doesn't return any data analyzed by ZXing.



This is the following code i'm using for this:



#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);
}
}









share|improve this question



























    0















    I'm trying to read a QR code with the following libraries:




    • ARKit

    • ZXing


    However it doesn't seem to go well. After several hours I still don't manage to read out a decent QR code.
    When debugging i apply the texture to see my result. It looks red because of the Texture Y but other than that it shows the QR code.
    Interpreting the texture doesn't return any data analyzed by ZXing.



    This is the following code i'm using for this:



    #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);
    }
    }









    share|improve this question

























      0












      0








      0


      2






      I'm trying to read a QR code with the following libraries:




      • ARKit

      • ZXing


      However it doesn't seem to go well. After several hours I still don't manage to read out a decent QR code.
      When debugging i apply the texture to see my result. It looks red because of the Texture Y but other than that it shows the QR code.
      Interpreting the texture doesn't return any data analyzed by ZXing.



      This is the following code i'm using for this:



      #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);
      }
      }









      share|improve this question














      I'm trying to read a QR code with the following libraries:




      • ARKit

      • ZXing


      However it doesn't seem to go well. After several hours I still don't manage to read out a decent QR code.
      When debugging i apply the texture to see my result. It looks red because of the Texture Y but other than that it shows the QR code.
      Interpreting the texture doesn't return any data analyzed by ZXing.



      This is the following code i'm using for this:



      #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);
      }
      }






      c# unity3d zxing arkit






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Nov 22 '18 at 13:10









      Maxim GeerinckMaxim Geerinck

      1,73952650




      1,73952650
























          2 Answers
          2






          active

          oldest

          votes


















          1





          +50









          I have worked with both ZXing and ARkit but never together.



          Tried to get something working to at least give you a hint on what could be possible.



          As a child of your ARCameraManager, add another (additionally to your main AR camera) camera with an ARVideo script attached to it (remove things like audio Listener, Flare layer and guiLayer) Also add the following script, which is just there to retrieve the renderTexture:



          [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;
          }
          }


          }



          Then use a script such as:



          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;
          }
          }


          Worked for me. The texture retrieval might not be the most efficient one.
          BUT it works -> it IS possible.






          share|improve this answer
























          • Thank you for your comment, i've also added an answer in which i explained for which solution i went.

            – Maxim Geerinck
            Nov 27 '18 at 14:47











          • is the question answered now? or still open?

            – Daveloper
            Nov 28 '18 at 9:18



















          0














          After some further digging i came across an example that had something similar for OpenCV.



          This proven to work for me with a good speed.



          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();
          }
          }


          I attached it to the main camera where the AR scripts where also attached under. Then i the qr code reader i could simply use the following:



          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;

          }
          }


          original source where i adapted this answer to: https://github.com/realityenhanced/ARKitExperiments/blob/master/Assets/Scripts/CaptureCenterPixel.cs






          share|improve this answer























            Your Answer






            StackExchange.ifUsing("editor", function () {
            StackExchange.using("externalEditor", function () {
            StackExchange.using("snippets", function () {
            StackExchange.snippets.init();
            });
            });
            }, "code-snippets");

            StackExchange.ready(function() {
            var channelOptions = {
            tags: "".split(" "),
            id: "1"
            };
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function() {
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled) {
            StackExchange.using("snippets", function() {
            createEditor();
            });
            }
            else {
            createEditor();
            }
            });

            function createEditor() {
            StackExchange.prepareEditor({
            heartbeatType: 'answer',
            autoActivateHeartbeat: false,
            convertImagesToLinks: true,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: 10,
            bindNavPrevention: true,
            postfix: "",
            imageUploader: {
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            },
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            });


            }
            });














            draft saved

            draft discarded


















            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53431781%2fread-qr-code-in-unity-with-arkit-and-zxing%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown

























            2 Answers
            2






            active

            oldest

            votes








            2 Answers
            2






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes









            1





            +50









            I have worked with both ZXing and ARkit but never together.



            Tried to get something working to at least give you a hint on what could be possible.



            As a child of your ARCameraManager, add another (additionally to your main AR camera) camera with an ARVideo script attached to it (remove things like audio Listener, Flare layer and guiLayer) Also add the following script, which is just there to retrieve the renderTexture:



            [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;
            }
            }


            }



            Then use a script such as:



            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;
            }
            }


            Worked for me. The texture retrieval might not be the most efficient one.
            BUT it works -> it IS possible.






            share|improve this answer
























            • Thank you for your comment, i've also added an answer in which i explained for which solution i went.

              – Maxim Geerinck
              Nov 27 '18 at 14:47











            • is the question answered now? or still open?

              – Daveloper
              Nov 28 '18 at 9:18
















            1





            +50









            I have worked with both ZXing and ARkit but never together.



            Tried to get something working to at least give you a hint on what could be possible.



            As a child of your ARCameraManager, add another (additionally to your main AR camera) camera with an ARVideo script attached to it (remove things like audio Listener, Flare layer and guiLayer) Also add the following script, which is just there to retrieve the renderTexture:



            [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;
            }
            }


            }



            Then use a script such as:



            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;
            }
            }


            Worked for me. The texture retrieval might not be the most efficient one.
            BUT it works -> it IS possible.






            share|improve this answer
























            • Thank you for your comment, i've also added an answer in which i explained for which solution i went.

              – Maxim Geerinck
              Nov 27 '18 at 14:47











            • is the question answered now? or still open?

              – Daveloper
              Nov 28 '18 at 9:18














            1





            +50







            1





            +50



            1




            +50





            I have worked with both ZXing and ARkit but never together.



            Tried to get something working to at least give you a hint on what could be possible.



            As a child of your ARCameraManager, add another (additionally to your main AR camera) camera with an ARVideo script attached to it (remove things like audio Listener, Flare layer and guiLayer) Also add the following script, which is just there to retrieve the renderTexture:



            [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;
            }
            }


            }



            Then use a script such as:



            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;
            }
            }


            Worked for me. The texture retrieval might not be the most efficient one.
            BUT it works -> it IS possible.






            share|improve this answer













            I have worked with both ZXing and ARkit but never together.



            Tried to get something working to at least give you a hint on what could be possible.



            As a child of your ARCameraManager, add another (additionally to your main AR camera) camera with an ARVideo script attached to it (remove things like audio Listener, Flare layer and guiLayer) Also add the following script, which is just there to retrieve the renderTexture:



            [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;
            }
            }


            }



            Then use a script such as:



            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;
            }
            }


            Worked for me. The texture retrieval might not be the most efficient one.
            BUT it works -> it IS possible.







            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Nov 27 '18 at 14:41









            DaveloperDaveloper

            3189




            3189













            • Thank you for your comment, i've also added an answer in which i explained for which solution i went.

              – Maxim Geerinck
              Nov 27 '18 at 14:47











            • is the question answered now? or still open?

              – Daveloper
              Nov 28 '18 at 9:18



















            • Thank you for your comment, i've also added an answer in which i explained for which solution i went.

              – Maxim Geerinck
              Nov 27 '18 at 14:47











            • is the question answered now? or still open?

              – Daveloper
              Nov 28 '18 at 9:18

















            Thank you for your comment, i've also added an answer in which i explained for which solution i went.

            – Maxim Geerinck
            Nov 27 '18 at 14:47





            Thank you for your comment, i've also added an answer in which i explained for which solution i went.

            – Maxim Geerinck
            Nov 27 '18 at 14:47













            is the question answered now? or still open?

            – Daveloper
            Nov 28 '18 at 9:18





            is the question answered now? or still open?

            – Daveloper
            Nov 28 '18 at 9:18













            0














            After some further digging i came across an example that had something similar for OpenCV.



            This proven to work for me with a good speed.



            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();
            }
            }


            I attached it to the main camera where the AR scripts where also attached under. Then i the qr code reader i could simply use the following:



            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;

            }
            }


            original source where i adapted this answer to: https://github.com/realityenhanced/ARKitExperiments/blob/master/Assets/Scripts/CaptureCenterPixel.cs






            share|improve this answer




























              0














              After some further digging i came across an example that had something similar for OpenCV.



              This proven to work for me with a good speed.



              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();
              }
              }


              I attached it to the main camera where the AR scripts where also attached under. Then i the qr code reader i could simply use the following:



              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;

              }
              }


              original source where i adapted this answer to: https://github.com/realityenhanced/ARKitExperiments/blob/master/Assets/Scripts/CaptureCenterPixel.cs






              share|improve this answer


























                0












                0








                0







                After some further digging i came across an example that had something similar for OpenCV.



                This proven to work for me with a good speed.



                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();
                }
                }


                I attached it to the main camera where the AR scripts where also attached under. Then i the qr code reader i could simply use the following:



                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;

                }
                }


                original source where i adapted this answer to: https://github.com/realityenhanced/ARKitExperiments/blob/master/Assets/Scripts/CaptureCenterPixel.cs






                share|improve this answer













                After some further digging i came across an example that had something similar for OpenCV.



                This proven to work for me with a good speed.



                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();
                }
                }


                I attached it to the main camera where the AR scripts where also attached under. Then i the qr code reader i could simply use the following:



                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;

                }
                }


                original source where i adapted this answer to: https://github.com/realityenhanced/ARKitExperiments/blob/master/Assets/Scripts/CaptureCenterPixel.cs







                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Nov 27 '18 at 14:45









                Maxim GeerinckMaxim Geerinck

                1,73952650




                1,73952650






























                    draft saved

                    draft discarded




















































                    Thanks for contributing an answer to Stack Overflow!


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid



                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.


                    To learn more, see our tips on writing great answers.




                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function () {
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53431781%2fread-qr-code-in-unity-with-arkit-and-zxing%23new-answer', 'question_page');
                    }
                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown







                    Popular posts from this blog

                    MongoDB - Not Authorized To Execute Command

                    How to fix TextFormField cause rebuild widget in Flutter

                    Npm cannot find a required file even through it is in the searched directory