Save rendering to file efficiently

Hello, I am in need of some of your expertise so I would be very helpful for any and all help I may get.

  • What do I want?
    I’m working on a project where I got a Scene Capture 2D and I want to render this scene and save the rendering to a file, preferably in a img format I guess?

  • Why?
    Cause I want to use FFMPEG to then stream this as a video sequence over the network to a website.

  • What do I have?
    Basically I am currently able to save it as a PNG file, however for some weird reasons I’m unable to use the Alpha part of my color buffer, I don’t know why but I found a workaround on the forums here.
    My current code:

    // Fill out your copyright notice in the Description page of Project Settings.

    #include “UnrealStream.h”
    #include “StreamHelper.h”
    #include <HighResScreenshot.h>
    #include
    #include
    #include

    FILE* UStreamHelper::f = nullptr;
    FString UStreamHelper::filePath = “C:\US\”;

    TArray UStreamHelper::GetColorBuffer(UTextureRenderTarget2D* RenderTarget)
    {
    //ColorBuffer.Reset();
    TArray ColorBuffer;
    FString Filename = filePath+“US.png”;

      if (RenderTarget != NULL)
      {
      	FIntRect SourceRect;
    
      	// Size/resolution of the saved image
      	FIntPoint DestSize(RenderTarget->GetSurfaceWidth(), RenderTarget->GetSurfaceHeight());
      	FString ResultPath;
      	FHighResScreenshotConfig& HighResScreenshotConfig = GetHighResScreenshotConfig();
    
      	FTextureRenderTarget2DResource* textureResource = (FTextureRenderTarget2DResource*)RenderTarget->Resource;
    
      	// Read the pixels of my resource and output it to the color buffer
      	if (textureResource->ReadPixels(ColorBuffer))
      	{
      		// The alpha workaround I found online involves setting the Alpha to 255
      		for (FColor& color : ColorBuffer) {
      			color.A = 255;
      		}
      		HighResScreenshotConfig.SaveImage(Filename, ColorBuffer, DestSize, &ResultPath);
    
      		// Before I decided to save the texture to an image I had ideas to just stream the colorbuffer to FFMPEG
      		return ColorBuffer;
      	}
      }
      return ColorBuffer;
    

    }

    // Used for FFMPEG
    void UStreamHelper::StartStream(int x, int y) {
    std::ofstream file;
    file.open(“tmp.us”, std::ios::out);
    file.close();
    //f = _popen((“C:\Users\SimpleCookie\Videos\ffmpeg-20160428-git-78baa45-win64-static\ffmpeg-20160428-git-78baa45-win64-static\bin\ffmpeg.exe -s " + std::to_string(x) + “x” + std::to_string(y) + " -i tmp.us -codec:v libx264 -crf 20 outfile_crf20.mkv”).c_str(), “w”);
    f = _popen((“C:\Users\SimpleCookie\Videos\ffmpeg-20160428-git-78baa45-win64-static\ffmpeg-20160428-git-78baa45-win64-static\bin\ffmpeg.exe -s " + std::to_string(x) + “x” + std::to_string(y) + " -i C:\US\tmp.us -codec:v libx264 -crf 20 C:\US\outfile_crf20.mkv”).c_str(), “r”);
    //system((“start C:\Users\SimpleCookie\Videos\ffmpeg-20160428-git-78baa45-win64-static\ffmpeg-20160428-git-78baa45-win64-static\bin\ffmpeg.exe -s " + std::to_string(x) + “x” + std::to_string(y) + " -i C:\US\tmp.us -codec:v libx264 -crf 20 C:\US\outfile_crf20.mkv”).c_str());
    }

    // Used for FFMPEG
    void UStreamHelper::StopStream() {
    //system(“taskkill /F /IM ffmpeg.exe”);
    _pclose(f);
    }

    // Used for FFMPEG
    void UStreamHelper::EncodeColorBuffer(TArray ColorBuffer) {
    std::ofstream file;
    file.open(“C:\US\tmp.us”, std::ios::out);
    try
    {
    UE_LOG(LogBlueprintUserMessages, Log, TEXT(“open: %d”), (int)file.is_open());
    }
    catch (const std::exception&)
    {

      }
      if (file.is_open()) {
      	for (auto &color : ColorBuffer) {
      		//file.write((char*)(&color), sizeof(color));
      		uint32 u = color.ToPackedRGBA();
      		file.write((char*)(&u), sizeof(u));
      		//file << color.R << color.G << color.B << color.A;
      	}
      }
      char ch[1024] = "123456789";
      char* q = fgets(ch, sizeof(ch), f);
      FString Fs = FString(ANSI_TO_TCHAR(q));
      if (f != 0)
      	UE_LOG(LogBlueprintUserMessages, Log, TEXT("Ch! %s"), *Fs);
      file.close();
    

    }

  • Why is my current solution bad?
    Because it’s incredibly inefficient. It’s very time consuming to read the pixels as I’m doing right now. Is it possible to just save the color buffer directly from the scene capture 2D or do I really have to read the pixels before I save them? It feels incredibly weird and unnecessary.

Honestly, if someone can give me a good solution, I can pay a small helping fee as a donation (if it’s allowed?). Cause I do believe help should be rewarded… though, a small one cause I’m a poor student ;D but I would at least want to show my gratitude. (through paypal preferably)

I get the same thing for a half year now…
Did you find a way ?

Hey @,

Thanks for getting back to me!
For now I have somehow similar solution - and I hate it each time I remember that I have a redundant copies :).

Honestly, I cannot remember if I did a better solution or not. I don’t believe I did. But if you’re interested in my solution, it’s available here on Github.
I hope it helps.

Yeah exactly :smiley: