Exporting as PNG fails

Hi,

I am trying to use ExportToDisk to save a camera projection as png file on disk. Here is the code, that I am using

void AScreenCaptureCameraActor::TickActor(float DeltaTime, enum ELevelTick TickType, FActorTickFunction& ThisTickFunction) {
	if (this->mScreenNeedsToBeCaptured) {
		UE_LOG(LogTemp, Warning, TEXT("Screen needs to be captured."));
		this->mScreenNeedsToBeCaptured = false;

		UTextureRenderTarget2D *renderTarget2D = mSceneCaptureComponent->TextureTarget;
		if (planeScreenMaterial != nullptr and planeScreenActor != nullptr) {
			UMaterialInstanceDynamic* dynamicMaterial = UMaterialInstanceDynamic::Create(planeScreenMaterial, this);
			dynamicMaterial->SetTextureParameterValue(FName("DebugTexture"), renderTarget2D);
			this->planeScreenActor->GetStaticMeshComponent()->SetMaterial(0, dynamicMaterial);
			this->SaveImageOnDisk(renderTarget2D);
		}
		else {
			UE_LOG(LogTemp, Warning, TEXT("Please set plane screen actor and material."));
		}
	}
	Super::TickActor(DeltaTime, TickType, ThisTickFunction);
}

void AScreenCaptureCameraActor::SetupSceneCaptureComponment() {

	UCameraComponent* currentCamera = this->GetCameraComponent();
	FMinimalViewInfo minimalViewInfo;
	currentCamera->GetCameraView(0, minimalViewInfo); // first argument is delta time.

	mSceneCaptureComponent = mSceneCaptureActor->GetCaptureComponent2D();
	mSceneCaptureComponent->SetCameraView(minimalViewInfo);
	mSceneCaptureComponent->bAlwaysPersistRenderingState = true;
	mSceneCaptureComponent->CaptureSource = ESceneCaptureSource::SCS_FinalColorLDR;
	mSceneCaptureComponent->bCaptureOnMovement = false;
	mSceneCaptureComponent->bCaptureEveryFrame = false;
	mSceneCaptureComponent->MaxViewDistanceOverride = -1.0f;
	mSceneCaptureComponent->bAutoActivate = true;
	mSceneCaptureComponent->DetailMode = EDetailMode::DM_High;
}

void AScreenCaptureCameraActor::CaptureScene() {
	FTransform cameraWorldTransform = this->GetCameraComponent()->GetComponentTransform();
	mSceneCaptureComponent->SetWorldTransform(cameraWorldTransform);

	UTextureRenderTarget2D* renderTarget2D = NewObject<UTextureRenderTarget2D>();
	renderTarget2D->ClearColor = FLinearColor::Blue;
	renderTarget2D->InitAutoFormat(IMG_WIDTH, IMG_HEIGHT);
	renderTarget2D->RenderTargetFormat = ETextureRenderTargetFormat::RTF_RGBA8;

	UCameraComponent* currentCamera = this->GetCameraComponent();
	FMinimalViewInfo minimalViewInfo;
	currentCamera->GetCameraView(0, minimalViewInfo); // first argument is delta time.

	mSceneCaptureComponent->SetCameraView(minimalViewInfo);
	mSceneCaptureComponent->bAlwaysPersistRenderingState = true;
	mSceneCaptureComponent->CaptureSource = ESceneCaptureSource::SCS_FinalColorLDR;
	mSceneCaptureComponent->TextureTarget = renderTarget2D;

	mSceneCaptureComponent->CaptureScene();

	this->mScreenNeedsToBeCaptured = true;
}

void AScreenCaptureCameraActor::CompleteImage() {
	UE_LOG(LogTemp, Warning, TEXT("Image saved."));
}

void AScreenCaptureCameraActor::SaveImageOnDisk(UTextureRenderTarget2D* texture2D) {
	texture2D->UpdateResourceImmediate(false);

	FImageWriteOptions options;
	options.bAsync = false;
	options.bOverwriteFile = true;
	options.Format = EDesiredImageFormat::PNG;
	options.OnComplete.BindUFunction(this, "CompleteImage");
	options.CompressionQuality = 100;

	FString ResultPath = FPaths::ProjectContentDir() + "/SCREENSHOTS/" + "0.png";
	UE_LOG(LogTemp, Warning, TEXT("Saving Image."));
	UImageWriteBlueprintLibrary::ExportToDisk(texture2D, ResultPath, options);
	texture2D->UpdateResourceImmediate(true);
}

However, I am getting this error when I try to export as PNG.

LogScript: Error: Script Msg: Only EXR export is currently supported for PF_FloatRGBA and PF_A32B32G32R32F formats.

I have heard about changing compression settings to UserInterface2D, however in renderTarget the compression settings does not have UserInterface2D option. Any pointers will really help. Thank you.

Hi @SoulslayerEldin,

If I remember correctly, PNG can only be export with PF_B8G8R8A8 which is suitable for most 8-bit RGBA textures.
PF_FloatRGBA and PF_A32B32G32R32F is used for HDR images which is why it’s complaining.

Try this:
UTextureRenderTarget2D* renderTarget2D = NewObject<UTextureRenderTarget2D>();
renderTarget2D->ClearColor = FLinearColor::Blue;
renderTarget2D->InitCustomFormat(IMG_WIDTH, IMG_HEIGHT, PF_B8G8R8A8, true); // Change this
renderTarget2D->RenderTargetFormat = ETextureRenderTargetFormat::RTF_RGBA8;

Hope this helps.

Thanks. I made the changes and the error went away. However, the resulting png image is blank. Any idea why?

Hey,

Not to sure. Could be a few different reasons.

I’d start with the Render Target. Looks like the image is being create but not capturing anything.
Assign the render target UTextureRenderTarget2D to a material and apply it to a plane or UI widget in the editor. Should at least see something here.

I attached the render target to a plane. I can see it just fine.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.