Download

ExportRenderTarget2DAsPNG comes out 0 bytes. Whatimiss?

I’m creating a screenshot for my save game class - cobbled together from codeI found online. It works pretty well, but the png file comes out 0 bytes. I’m obviously missing something, but not finding it in the documentation. Suggestions?



// AVRPawn holds the camera and capture component
AVRPawn::AVRPawn()
{
    PrimaryActorTick.bCanEverTick = false;

    VRRoot = CreateDefaultSubobject<USceneComponent>(TEXT("VRRoot"));
    SetRootComponent(VRRoot);

    Camera = CreateDefaultSubobject<UCameraComponent>(TEXT("Camera"));
    Camera->SetupAttachment(VRRoot);

    SceneCapture = CreateDefaultSubobject<USceneCaptureComponent2D>(TEXT("SceneCapture"));
    SceneCapture->SetupAttachment(Camera);
    SceneCapture->bCaptureEveryFrame = false;
}

void AVRPawn::BeginPlay()
{
    Super::BeginPlay();

    // snip setup controllers

    UTextureRenderTarget2D* TextureRenderTarget = NewObject<UTextureRenderTarget2D>();
    TextureRenderTarget->InitAutoFormat(512, 512);

    // Setting the new target
    SceneCapture->TextureTarget = TextureRenderTarget;

}


And then in my save game class, I try this:




void UPainterSaveGame::SaveThumbnail(USceneCaptureComponent2D* SceneCapture)
{
    FString ThumbnailFile = GetThumbnailFilePath();
    FText PathError;
    FPaths::ValidatePath(ThumbnailFile, &PathError);

    // Capturing the scene.
    SceneCapture->CaptureScene();

    // Save to disc
    UTextureRenderTarget2D* TextureRenderTarget = SceneCapture->TextureTarget;
    if (TextureRenderTarget == nullptr)
    {
        UE_LOG(LogTemp, Warning, TEXT("SaveThumbnail failed: TextureRenderTarget must be non-null."));
    }
    else if (!TextureRenderTarget->Resource)
    {
        UE_LOG(LogTemp, Warning, TEXT("SaveThumbnail failed: render target has been released."));
    }
    else if (!PathError.IsEmpty())
    {
        UE_LOG(LogTemp, Warning, TEXT("SaveThumbnail failed: Invalid file path"));
    }
    else
    {
        FArchive* Ar = IFileManager::Get().CreateFileWriter(*ThumbnailFile);

        if (Ar)
        {
            FBufferArchive Buffer;

            bool bSuccess = FImageUtils::ExportRenderTarget2DAsPNG(TextureRenderTarget, Buffer);

            if (bSuccess)
            {
                Ar->Serialize(const_cast<uint8*>(Buffer.GetData()), Buffer.Num());
            }

            delete Ar;
        }
        else
        {
            UE_LOG(LogTemp, Warning, TEXT("SaveThumbnail failed: FileWrite failed to create."));
        }
    }
}


The file gets there, but it’s 0 bytes. I’m not concerned about performance - I’m taking this as a challenge to explore this part of the API, so the simplest thing that could possibly work is great.

Am I using the right classes?
What am I missing?

Thanks in advance!

Michael

I think ExportRenderTarget2DAsPNG is exporting only HDR pictures whih means only EXR format.
You can use this which makes the write operation async and gives more feedback on what texture format matches what export type: UImageWriteBlueprintLibrary::ExportToDisk | Unreal Engine Documentation

To verify but I think Export PNG is only possible with this format ETextureRenderTargetFormat::RTF_RGBA16f, which means having the render target capturing FinalColor_LDR, other ones will need to be exported in EXR. Or if you need some specific format in PNG you need to convert it manually.