C++ screenshot GetViewportScreenShot returning all black pixels

I have the following problem that I cannot find an answer to online.
I am making a screenshot, I need it to actually be low res (for networking reasons, not important here) and when doing it in Editor World everything works fine, but when using it in game mode, everything goes through, does not throw any errors, but the image is black.
After calling GetViewportScreenShot() on the correct (i guess) viewport every pixel is RBG black.
I dont need actual file on disk, I just need the binary image so I’m doing it like this.

After a few iterations, i separated the Editor mode and game mode functions, and the game mode looks like this, does anyone know what the problem could be, and how to take a screenshot (in non high res mode) in Game World?
This code is where I’m currently now so its not perfect but it creates the image that is black.and tells the story :slight_smile:
Thanks!

This code produces a perfect screenshot that i need, in editor mode:(GetImageWrapper is just initing of the ImageWrapper module for JPEG)

FViewport* Viewport = GEditor->GetActiveViewport();
double StartScreenshotTime = FPlatformTime::Seconds();
TArray<FColor> ViewportPixels;
FIntRect ViewRect(0, 0, Viewport->GetSizeXY().X, Viewport->GetSizeXY().Y);

bool bDidGetScreenShot = GetViewportScreenShot(Viewport, ViewportPixels, ViewRect);

GetImageWrapper()->SetRaw(&ViewportPixels[0], ViewportPixels.Num() * sizeof(FColor), Viewport->GetSizeXY().X, Viewport->GetSizeXY().Y, ERGBFormat::BGRA, 8);
const TArray64<uint8> CompressedImage = GetImageWrapper()->GetCompressed(Quality);

return CompressedImage;

This code produces a black image

UGameViewportClient* GameViewport = GEngine->GameViewport;

FVector2D ViewportSize;
GameViewport->GetViewportSize(ViewportSize);
FIntRect Rect(0, 0, ViewportSize.X, ViewportSize.Y);

FViewport* Viewport = GameViewport->Viewport;
TArray<FColor> ViewportPixels;
GetViewportScreenShot(Viewport, ViewportPixels, Rect);

GetImageWrapper()->SetRaw(&Viewport[0], ViewportPixels.Num() * sizeof(FColor), Viewport->GetSizeXY().X, Viewport->GetSizeXY().Y, ERGBFormat::RGBA, 8);
const TArray64<uint8> CompressedImage = GetImageWrapper()->GetCompressed(Quality);
return CompressedImage;

For future travelers

I managed to get this working with a totally different method, not sure if it’s the best method, but it works!

TArray64<uint8> MyClass::GetScreenShotInGame(int Quality)
{
    TArray<FColor> ViewportPixels;
    FIntVector OutSize;
    FSlateApplication::Get().TakeScreenshot( GEngine->GameViewport->GetWindow().ToSharedRef(), ViewportPixels, OutSize);

    GetImageWrapper()->SetRaw(&ViewportPixels[0], ViewportPixels.Num() * sizeof(FColor), OutSize.X, OutSize.Y, ERGBFormat::BGRA, 8);
    const TArray64<uint8> CompressedImage = GetImageWrapper()->GetCompressed(Quality);
    return CompressedImage;
}
1 Like

Through FSlateApplication::Get().TakeScreenshot ,It works. Thanks verymuch. I hava tried to use FScreenshotRequest::RequestScreenshot And ScreenshotCapturedDelegate。But some Problem,this picture is white。 In the future,hope to find different ways.

Hello,I fix it well. I can use this three line code finsh mywork both in runtime and editor.
(also you can refer to offical example.AScreenshotFunctionalTest::RequestScreenshot():wink:
1.I reister my callbackmethod before I begin to screen shot :
FlushRenderingCommands();
UGameViewportClient::OnScreenshotCaptured().AddUObject(this, &???::CallbackScreenShot);

2.Callback Method ,where you can do real work in one frame data:
UFUNCTION()
void CallbackScreenShot(int32 InWidth, int32 InHeight, const TArray& InColors);

3.Finally,I call shotscreen When I need:
FScreenshotRequest::RequestScreenshot(false);

4.Sometime ,maybe you should clean this delegete and handle ,when you do not need it.

So,I can generate webp from multi shot screen data.

1 Like