Texture2D.ReadPixels correct coordinates

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?

Rect rect = new Rect (photoPanel.GetComponent<RectTransform> ().rect);

Texture2D tex = new Texture2D((int)rect.width, (int)rect.height);

tex.ReadPixels (rect, 0, 0);

tex.Apply();

I did a quick test like so:

RectTransform rt = img.GetComponent<RectTransform>();
Rect rect = new Rect(new Vector2(rt.position.x, rt.position.y),new Vector2(rt.sizeDelta.x, rt.sizeDelta.y));
print("rect is : " + rect);

Which gave me what seemed right :slight_smile: * may have to modify the pivot, too.

HI, thanks so I altered my code to this:

RectTransform rt = photoPanel.GetComponent<RectTransform>();
Rect rect = new Rect(new Vector2(rt.position.x, rt.position.y),new Vector2(rt.sizeDelta.x, rt.sizeDelta.y));
Texture2D tex = new Texture2D((int)rect.width, (int)rect.height);
tex.ReadPixels (rect,0,0);
tex.Apply();

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.
:frowning:

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).

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

aspectRatioFitter.aspectRatio = (float)tex.width / (float)tex.height;

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.

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?

Just for fun, please try setting the pivot to the bottom left & see what values you get :slight_smile:

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

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?

The AspectRatioFitter overrides the value 0 back to 1

:frowning:

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.

1 Like

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 :(:(:frowning:

Disabling the AspectFitterRation results in:

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

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

Updated code in case my explanation sucked:

RectTransform rt = img.GetComponent<RectTransform>();
Rect rect = new Rect(new Vector2(rt.position.x, rt.position.y),rt.rect.size);
print("rect is : " + rect);

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.

:face_with_spiral_eyes:

Googled that & found an answer which translates much like this:

     if (Input.GetKeyUp(KeyCode.A))
        {
            StartCoroutine(CaptureScreen());
        }
    }
    IEnumerator CaptureScreen()
    {
        yield return new WaitForEndOfFrame();
        RectTransform rt = img.GetComponent<RectTransform>();
        Rect rect = new Rect(new Vector2(rt.position.x, rt.position.y), rt.rect.size);
        print("rect is : " + rect);
        Texture2D tex = new Texture2D((int)rt.rect.size.x, (int)rt.rect.size.y);
        tex.ReadPixels(rect, 0, 0);
        tex.Apply();
    }

GetKeyUp was just for me to test :slight_smile: I no longer got the error. Didn’t do anything with the texture so can’t speak to that :slight_smile:

2 Likes

Well that seems to do the trick, crowd goes wild, Mexican wave…woot
:):):slight_smile:

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!

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 :slight_smile:
You may wish to look into that in online searches and/or post a new, and updated thread. Good luck to you :slight_smile:

1 Like

Thanks for all your help, really appreciate it :slight_smile: