TArray<uint8> UGTCaptureComponent::CapturePng(FString Mode) { // Flush location and rotation check(CaptureComponents.Num() != 0); USceneCaptureComponent2D* CaptureComponent = CaptureComponents.FindRef(Mode); TArray<uint8> ImgData; if (CaptureComponent == nullptr) return ImgData; // Attach this to something, for example, a real camera const FRotator PawnViewRotation = Pawn->GetViewRotation(); if (!PawnViewRotation.Equals(CaptureComponent->GetComponentRotation())) { CaptureComponent->SetWorldRotation(PawnViewRotation); } UTextureRenderTarget2D* RenderTarget = CaptureComponent->TextureTarget; static IImageWrapperModule& ImageWrapperModule = FModuleManager::LoadModuleChecked<IImageWrapperModule>(FName("ImageWrapper")); static TSharedPtr<IImageWrapper> ImageWrapper = ImageWrapperModule.CreateImageWrapper(EImageFormat::PNG); int32 Width = RenderTarget->SizeX, Height = RenderTarget->SizeY; TArray<FColor> Image; FTextureRenderTargetResource* RenderTargetResource; Image.AddZeroed(Width * Height); RenderTargetResource = RenderTarget->GameThread_GetRenderTargetResource(); FReadSurfaceDataFlags ReadSurfaceDataFlags; ReadSurfaceDataFlags.SetLinearToGamma(false); // This is super important to disable this! // Instead of using this flag, we will set the gamma to the correct value directly RenderTargetResource->ReadPixels(Image, ReadSurfaceDataFlags); ImageWrapper->SetRaw(Image.GetData(), Image.GetAllocatedSize(), Width, Height, ERGBFormat::BGRA, 8); ImgData = ImageWrapper->GetCompressed(); return ImgData; }
void SavePng(UTextureRenderTarget2D* RenderTarget, FString Filename) { SCOPE_CYCLE_COUNTER(STAT_SavePng); int32 Width = RenderTarget->SizeX, Height = RenderTarget->SizeY; TArray<FColor> Image; FTextureRenderTargetResource* RenderTargetResource; Image.AddZeroed(Width * Height); { SCOPE_CYCLE_COUNTER(STAT_GetResource); RenderTargetResource = RenderTarget->GameThread_GetRenderTargetResource(); } { SCOPE_CYCLE_COUNTER(STAT_ReadPixels); FReadSurfaceDataFlags ReadSurfaceDataFlags; ReadSurfaceDataFlags.SetLinearToGamma(false); // This is super important to disable this! // Instead of using this flag, we will set the gamma to the correct value directly RenderTargetResource->ReadPixels(Image, ReadSurfaceDataFlags); } TArray<uint8> ImgData = SerializationUtils::Image2Png(Image, Width, Height); FFileHelper::SaveArrayToFile(ImgData, *Filename); }
void AShaderPluginDemoCharacter::SaveRenderTargetToDisk(UTextureRenderTarget2D* InRenderTarget, FString Filename, bool debug) { FTextureRenderTargetResource* RTResource = InRenderTarget->GameThread_GetRenderTargetResource(); FReadSurfaceDataFlags ReadPixelFlags(RCM_UNorm); ReadPixelFlags.SetLinearToGamma(true); TArray<FColor> OutBMP; RTResource->ReadPixels(OutBMP, ReadPixelFlags); FIntRect SourceRect; FIntPoint DestSize(InRenderTarget->GetSurfaceWidth(), InRenderTarget->GetSurfaceHeight()); FString ResultPath; FHighResScreenshotConfig& HighResScreenshotConfig = GetHighResScreenshotConfig(); if (HighResScreenshotConfig.SaveImage(FPaths::GameSavedDir() + TEXT("Screenshots/") + Filename, OutBMP, DestSize, &ResultPath) && debug) { UE_LOG(LogFPChar, Warning, TEXT("Screenshot saved to: %s"), *ResultPath); } }
TArray<uint8> UGTCaptureComponent::CaptureNpyUint8(FString Mode, int32 Channels) { // Flush location and rotation check(CaptureComponents.Num() != 0); USceneCaptureComponent2D* CaptureComponent = CaptureComponents.FindRef(Mode); TArray<uint8> NpyData; if (CaptureComponent == nullptr) { UE_LOG(LogUnrealCV, Error, TEXT("Component for mode %s not found. Returning empty array."), *Mode); return NpyData; } // Attach this to something, for example, a real camera const FRotator PawnViewRotation = Pawn->GetViewRotation(); if (!PawnViewRotation.Equals(CaptureComponent->GetComponentRotation())) { CaptureComponent->SetWorldRotation(PawnViewRotation); } UTextureRenderTarget2D* RenderTarget = CaptureComponent->TextureTarget; int32 Width = RenderTarget->SizeX, Height = RenderTarget->SizeY; TArray<FColor> ImageData; FTextureRenderTargetResource* RenderTargetResource; ImageData.AddUninitialized(Width * Height); RenderTargetResource = RenderTarget->GameThread_GetRenderTargetResource(); FReadSurfaceDataFlags ReadSurfaceDataFlags; ReadSurfaceDataFlags.SetLinearToGamma(false); // This is super important to disable this! // Instead of using this flag, we will set the gamma to the correct value directly RenderTargetResource->ReadPixels(ImageData, ReadSurfaceDataFlags); // Check the byte order of data // Compress image data to npy array // Generate a header for the numpy array NpyData = NpySerialization(ImageData, Width, Height, Channels); return NpyData; }