Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Advice needed: Screen capture from OnRenderImage

Discussion in 'Image Effects' started by pyjamaslug, Sep 24, 2019.

  1. pyjamaslug

    pyjamaslug

    Joined:
    Jul 5, 2017
    Posts:
    51
    Hi,
    I'm capturing my screen using AsyncGPUReadback.Request from the OnRenderImage callback, as proposed in various bits of documentation I have seen. The capture works but the image is very dark by comparison to what I expect (and what I see on the display).
    I am reading the buffer as a byte array rather than using unity types like this:

    Code (CSharp):
    1. outputBundle.image = req.request.GetData<Byte>(0).ToArray();
    and using the bytes directly to set colors in my png encoder like this:

    Code (CSharp):
    1.                 pngUtility.pixels[i].red = buffer[i * 4];
    2.                 pngUtility.pixels[i].green = buffer[(i * 4) + 1];
    3.                 pngUtility.pixels[i].blue = buffer[(i * 4) + 2];
    4.                 pngUtility.pixels[i].alpha = buffer[(i * 4) + 3];
    where i points to the pixel.

    is there some other conversion I should be doing?
     
  2. pyjamaslug

    pyjamaslug

    Joined:
    Jul 5, 2017
    Posts:
    51
    Update:
    I am getting the same thing if I use this:
    Code (CSharp):
    1.                            
    2. var buffer = req.request.GetData<Color32>();
    3. var tex = new Texture2D(outputBundle.width, outputBundle.height, TextureFormat.RGBA32, false);
    4. tex.SetPixels32(buffer.ToArray());
    5. tex.Apply();
    6. File.WriteAllBytes(outputBundle.destinationFile, ImageConversion.EncodeToPNG(tex));
     
  3. pyjamaslug

    pyjamaslug

    Joined:
    Jul 5, 2017
    Posts:
    51
    So, yes it turns out there is indeed another conversion I needed to be doing. I have my camera set to allow HDR, which affects the format of the pixels. I don't know what the precise format is but I solved it by blitting to a rendertexture with RenderTextureFormat.ARGB32 which forces the correct conversion.