AsyncGPUReadbackRequest and EncodeToPNG isn't working

IEnumerator UploadPNG()
{
    // We should only read the screen buffer after rendering is complete
    yield return new WaitForEndOfFrame();

    // Create a texture the size of the screen, RGB24 format
    int width = Screen.width;
    int height = Screen.height;
    Texture2D tex = new Texture2D(width, height, TextureFormat.RGB24, false);

    // Read screen contents into the texture
    tex.ReadPixels(new Rect(0, 0, width, height), 0, 0);
    tex.Apply();
    // Encode texture into PNG
    byte[] bytes = ImageConversion.EncodeToJPG(tex, 2);
    //UnityEngine.Object.Destroy(tex);

    yield return ProcessBytes(bytes);
}

i was using this to captur screenshot but its really slow.

I heard that asynccapture is faster but don’t know how to convert it from readpixels to async. heres what i did:

void CaptureScreenOptimized()
{
    Texture2D texture = new(Screen.width, Screen.height, TextureFormat.RGBA32, false);

    AsyncGPUReadback.Request(texture, 0, TextureFormat.RGB24, request =>
    {
        var rawData = request.GetData<byte>();
        texture.LoadRawTextureData(rawData);
        texture.Apply();
        byte[] bytes = ImageConversion.EncodeToJPG(texture, 15);

        SendImage(bytes);
    });
}

I am getting the exception : MissingReferenceException: The object of type Texture2D has been destroyed but you are still trying to access it."
UnityException: LoadRaw TextureData: not enough data provided

this is not working, anyone knows how to solve this?

I’m not super-familiar with this API AsyncGPUReadback.Request() but you may need to marshal that onto the main thread to run the callback.

If this callback is already using the main thread then disregard this statement.

It is using the main thread already. Thanks for replying tho Kurt.

1 Like

size mismatch between request and actual size, hence the “not enough data provided” error

Edit: I am also not familiar with AsyncGPUReadback but it feels like you are trying to read the texture back to itself??
Edit2: also you are trying to capture the screen, async probably isn’t the way to do this. I found this official capture method if you want to take a look Unity - Scripting API: ScreenCapture.CaptureScreenshot

1 Like