Search Unity

Texture2D.ReadPixels correct coordinates

Discussion in 'UGUI & TextMesh Pro' started by elpuerco63, May 27, 2017.

  1. elpuerco63

    elpuerco63

    Joined:
    Jun 26, 2014
    Posts:
    271
    I am trying to capture the area of the screen taken up by a photo using the code below.

    Although I am getting the correct sized texture output I am only getting the bottom left area of the screen and not the photo.

    I guess this is because all examples of ReadPixels I find have destX and destY set to 0,0 which is bottom left.

    I know the problem is probably to do with the 0,0 but not sure what I am supposed to put there?

    Code (csharp):
    1.  
    2. Rect rect = new Rect (photoPanel.GetComponent<RectTransform> ().rect);
    3.  
    4. Texture2D tex = new Texture2D((int)rect.width, (int)rect.height);
    5.  
    6. tex.ReadPixels (rect, 0, 0);
    7.  
    8. tex.Apply();
    9.  
    https://ibb.co/f1ktha
     
  2. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    I did a quick test like so:
    Code (csharp):
    1.  
    2. RectTransform rt = img.GetComponent<RectTransform>();
    3. Rect rect = new Rect(new Vector2(rt.position.x, rt.position.y),new Vector2(rt.sizeDelta.x, rt.sizeDelta.y));
    4. print("rect is : " + rect);
    5.  
    Which gave me what seemed right :) * may have to modify the pivot, too.
     
  3. elpuerco63

    elpuerco63

    Joined:
    Jun 26, 2014
    Posts:
    271
    HI, thanks so I altered my code to this:

    Code (csharp):
    1.  
    2. RectTransform rt = photoPanel.GetComponent<RectTransform>();
    3. Rect rect = new Rect(new Vector2(rt.position.x, rt.position.y),new Vector2(rt.sizeDelta.x, rt.sizeDelta.y));
    4. Texture2D tex = new Texture2D((int)rect.width, (int)rect.height);
    5. tex.ReadPixels (rect,0,0);
    6. tex.Apply();
    7.  
    Looking in the editor using the print rect line I get this:
    rect is : (x:540.00, y:960.00, width:0.00, height:-230.94)

    Pivot is set t0 0.5, 0.5

    And the app crashes with the error:
    Failed to create texture because of invalid parameters.

    :(
     
    Last edited: May 28, 2017
  4. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    Sorry to hear that. Did you debug the values of the rect before the texture creation?

    I didn't setup my test to be the same as yours. I didn't create a texture, nor did I try to read its pixels, etc..
    I only tested getting the proper position of a RectTransform in the canvas (and size).
     
  5. elpuerco63

    elpuerco63

    Joined:
    Jun 26, 2014
    Posts:
    271
    Yes, the line immediately after rect is created and before texture creation attempt gives:

    rect is : (x:540.00, y:960.00, width:0.00, height:-230.94)

    So as you see a width of zero and a height of -230.94 is invalid I guess.

    Note these values are enforced by the AspectRatioFitter set to Fit In Parent with its ratio set when the photo is loaded from gallery or from camera like so

    Code (csharp):
    1.  
    2. aspectRatioFitter.aspectRatio = (float)tex.width / (float)tex.height;
    3.  
     
  6. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    well, obviously we can't create a texture of 0, and negative lol.
    Did you try to adjust the pivot as I mentioned? (dunno if anchor is needed , too, sometimes these things confused me) Just try to change that a bit. I made mine bottom left for simplicity. Of course you could keep the anchor/pivot and use math to sort out the difference. But easier to test by just changing it first and go from there, I'd think.
     
  7. elpuerco63

    elpuerco63

    Joined:
    Jun 26, 2014
    Posts:
    271
    Yeah lol

    I did move the pivot to top left but then that makes the photo start at top left of screen with a huge black border at bottom of the screen.

    I dont follow the 0 and - 230.94 values at all and why they dont show the actual with and height?
     
  8. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    Just for fun, please try setting the pivot to the bottom left & see what values you get :)
     
  9. elpuerco63

    elpuerco63

    Joined:
    Jun 26, 2014
    Posts:
    271
    I get this:
    rect is : (x:0.00, y:0.00, width:0.00, height:-230.94)

    I also tried to use the width and height of the photo as it is loaded into view and I get this:

    w = 2448 h = 3264

    But either way with pivot unchanged I now get:

    Negative read pixels rectangle width|height
     
  10. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    Okay, I just got some negative values, also!

    So, the pivot (and why I adjusted mine to the bottom left, was to get the accurate position without having to adjust it mathematically.)
    The anchors affect the size, so without having to use math on the result, I set my anchors to all 0,0 and this gave me the proper results.
    Try that?
     
  11. elpuerco63

    elpuerco63

    Joined:
    Jun 26, 2014
    Posts:
    271
    The AspectRatioFitter overrides the value 0 back to 1

    :(
     
  12. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    Well, there is math to figure this out, but If you try without the aspect fitter thing, i think you'll see the right dimensions.
    So, maybe that will give you faith to continue lol

    You may have to work out the size somehow yourself. I'm experimenting but don't have a definite answer, yet.
     
    elpuerco63 likes this.
  13. elpuerco63

    elpuerco63

    Joined:
    Jun 26, 2014
    Posts:
    271
    Ok thanks, really appreciate your help. Will keep plodding on. I have to use the AspectRatioFitter to ensure the image displays correct across devices...

    Math is not my forte :(:(:(

    Disabling the AspectFitterRation results in:

    ReadPixels was called to read pixels from system frame buffer, while not inside drawing frame.
     
  14. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    I knew/figured you were going to keep the aspect ratio fitter. I just meant at least you could see that it's possible lol.

    In fact, I just found the answer, which came round about to using the ".rect"

    Just use rt.position.x/y as the previous example but instead of sizeDelta.x/y use "rt.rect.x/y"

    Bonus: didn't require any math on (our) part lol
     
  15. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    Updated code in case my explanation sucked:
    Code (csharp):
    1.  
    2. RectTransform rt = img.GetComponent<RectTransform>();
    3. Rect rect = new Rect(new Vector2(rt.position.x, rt.position.y),rt.rect.size);
    4. print("rect is : " + rect);
    5.  
     
  16. elpuerco63

    elpuerco63

    Joined:
    Jun 26, 2014
    Posts:
    271
    Cool thanks, tried that I get

    rect is : (x:540.00, y:960.00, width:519.62, height:692.82)

    ReadPixels was called to read pixels from system frame buffer, while not inside drawing frame.

    :confused:
     
  17. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    Googled that & found an answer which translates much like this:
    Code (csharp):
    1.  
    2.      if (Input.GetKeyUp(KeyCode.A))
    3.         {
    4.             StartCoroutine(CaptureScreen());
    5.         }
    6.     }
    7.     IEnumerator CaptureScreen()
    8.     {
    9.         yield return new WaitForEndOfFrame();
    10.         RectTransform rt = img.GetComponent<RectTransform>();
    11.         Rect rect = new Rect(new Vector2(rt.position.x, rt.position.y), rt.rect.size);
    12.         print("rect is : " + rect);
    13.         Texture2D tex = new Texture2D((int)rt.rect.size.x, (int)rt.rect.size.y);
    14.         tex.ReadPixels(rect, 0, 0);
    15.         tex.Apply();
    16.     }
    17.  
    GetKeyUp was just for me to test :) I no longer got the error. Didn't do anything with the texture so can't speak to that :)
     
    phatng45 and mdrunk like this.
  18. elpuerco63

    elpuerco63

    Joined:
    Jun 26, 2014
    Posts:
    271
    Well that seems to do the trick, crowd goes wild, Mexican wave...woot
    :):):)

    That snapped the correct screen portion and took the base photo but not the icons sitting on top? So it correctly took the screenshot at the required rect but objects I have as children to photopanel and in view are ignored?

    But awesome progress thanks!
     
  19. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    Oh, awesome. I'm glad you got it working (at least a portion). This thread made me learn a bit, too, but as for your children not appearing, I have no idea :)
    You may wish to look into that in online searches and/or post a new, and updated thread. Good luck to you :)
     
    elpuerco63 likes this.
  20. elpuerco63

    elpuerco63

    Joined:
    Jun 26, 2014
    Posts:
    271
    Thanks for all your help, really appreciate it :)
     
  21. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    No problem. Good luck with the finishing touches. :)
     
    elpuerco63 likes this.
  22. elpuerco63

    elpuerco63

    Joined:
    Jun 26, 2014
    Posts:
    271