UE4 FColor数据保存成图片

1、TArray<FColor>或是FColor*可通过ImageWrapper直接保存成图片

 1 void URenderCineCameraLibrary::SaveColorToFile(FColor* SourceColor, uint32 Width, uint32 Height)
 2 {
 3     check(SourceColor != nullptr);
 4     
 5     /*// FColor* SurfaceColor ...png
 6     for (FColor& Color : SurfaceColor)
 7     {
 8         Color.A = 255;
 9     }
10 
11     TArray<uint8> TextureData;
12     TextureData.AddUninitialized(Width * Height * sizeof(FColor));
13     FMemory::Memcpy(TextureData.GetData(), (uint8*)SourceColor, Width * Height * sizeof(FColor));
14     if (TextureData.Num() <= 0)
15     {
16         UE_LOG(LogTemp, Error, TEXT("TextureData is empty ..."));
17         return;
18     }*/
19 
20     // save png
21     IImageWrapperModule& ImageWrapperModule = FModuleManager::LoadModuleChecked<IImageWrapperModule>(FName("ImageWrapper"));
22     TSharedPtr<IImageWrapper> ImageWrapper = ImageWrapperModule.CreateImageWrapper(EImageFormat::JPEG);
23     ImageWrapper->SetRaw(SourceColor, Width * Height * sizeof(FColor), Width, Height, ERGBFormat::BGRA, 8);
24     
25 
26     const TArray64<uint8>& PNGData = ImageWrapper->GetCompressed(100);
27 
28     FString FileName = TEXT("D:\\CineCapture1.jpg");
29     FFileHelper::SaveArrayToFile(PNGData, *FileName);
30     ImageWrapper.Reset();
31 }

 

2、将UTexture2D保存成图片

 1 void URenderCineCameraLibrary::SaveTextureToFile(UTexture2D* SourceTex)
 2 {
 3     check(SourceTex);
 4     int32 Width = SourceTex->GetSizeX();
 5     int32 Height = SourceTex->GetSizeY();
 6 
 7     FTexture2DMipMap& MipMap = SourceTex->GetPlatformData()->Mips[0];
 8     void* Data = MipMap.BulkData.Lock(LOCK_READ_ONLY);
 9 
10     TArray<uint8> TextureData;
11     TextureData.AddUninitialized(Width * Height * sizeof(FColor));
12     FMemory::Memcpy(TextureData.GetData(), (uint8*)Data, Width * Height * sizeof(FColor));
13     if (TextureData.Num() <= 0)
14     {
15         UE_LOG(LogTemp, Error, TEXT("TextureData is empty ..."));
16         return;
17     }
18 
19     // save png
20     IImageWrapperModule& ImageWrapperModule = FModuleManager::LoadModuleChecked<IImageWrapperModule>(FName("ImageWrapper"));
21     TSharedPtr<IImageWrapper> ImageWrapper = ImageWrapperModule.CreateImageWrapper(EImageFormat::JPEG);
22     ImageWrapper->SetRaw(TextureData.GetData(), Width * Height * sizeof(FColor), Width, Height, ERGBFormat::BGRA, 8);
23 
24 
25     const TArray64<uint8>& PNGData = ImageWrapper->GetCompressed(100);
26 
27     FString FileName = TEXT("D:\\CineTexture.jpg");
28     FFileHelper::SaveArrayToFile(PNGData, *FileName);
29     ImageWrapper.Reset();
30     
31 
32     MipMap.BulkData.Unlock();
33 }

 

3、创建UTextureRenderTarget2D、设置及保存为图片

  1 void URenderCineCameraLibrary::ConstructRT2D()
  2 {
  3     if (m_CineTexRT2D == nullptr)
  4     {
  5         m_CineTexRT2D = NewObject<UTextureRenderTarget2D>();
  6         m_CineTexRT2D->AddToRoot();
  7         m_CineTexRT2D->ClearColor = FLinearColor::Transparent;
  8         m_CineTexRT2D->TargetGamma = 0.f;
  9         m_CineTexRT2D->InitCustomFormat(/*m_CaptureViewport->m_ViewportX*/1920, /*m_CaptureViewport->m_ViewportY*/1080, PF_B8G8R8A8, false);
 10     }    
 11 
 12     check(GCineWorld != nullptr);
 13     check(m_CineCamTex != nullptr);
 14     CopyTextureToRenderTargetTexture(m_CineCamTex, m_CineTexRT2D, GCineWorld->FeatureLevel);
 15 
 16 // save 
 17     //SaveRenderTargetToFile(m_CineTexRT2D, TEXT("D:\\RT_Cine.jpg"));
 18 }
 19 
 20 //
 21 
 22 void URenderCineCameraLibrary::CopyTextureToRenderTargetTexture(UTexture* SourceTexture, UTextureRenderTarget2D* RenderTargetTexture, ERHIFeatureLevel::Type FeatureLevel)
 23 {
 24     check(SourceTexture != nullptr);
 25     check(RenderTargetTexture != nullptr);
 26 
 27     // Grab the actual render target resource from the texture.  Note that we're absolutely NOT ALLOWED to
 28     // dereference this pointer.  We're just passing it along to other functions that will use it on the render
 29     // thread.  The only thing we're allowed to do is check to see if it's nullptr or not.
 30     FTextureRenderTargetResource* RenderTargetResource = RenderTargetTexture->GameThread_GetRenderTargetResource();
 31     check(RenderTargetResource != nullptr);
 32 
 33     // Create a canvas for the render target and clear it to black
 34     FCanvas Canvas(RenderTargetResource, nullptr, FGameTime(), FeatureLevel);
 35 
 36     const uint32 Width = RenderTargetTexture->GetSurfaceWidth();
 37     const uint32 Height = RenderTargetTexture->GetSurfaceHeight();
 38 
 39     // @todo MeshPaint: Need full color/alpha writes enabled to get alpha
 40     // @todo MeshPaint: Texels need to line up perfectly to avoid bilinear artifacts
 41     // @todo MeshPaint: Potential gamma issues here
 42     // @todo MeshPaint: Probably using CLAMP address mode when reading from source (if texels line up, shouldn't matter though.)
 43 
 44     // @todo MeshPaint: Should use scratch texture built from original source art (when possible!)
 45     //        -> Current method will have compression artifacts!
 46 
 47     // Grab the texture resource.  We only support 2D textures and render target textures here.
 48     FTexture* TextureResource = nullptr;
 49     UTexture2D* Texture2D = Cast<UTexture2D>(SourceTexture);
 50     if (Texture2D != nullptr)
 51     {
 52         TextureResource = Texture2D->GetResource();
 53     }
 54     else
 55     {
 56         UTextureRenderTarget2D* TextureRenderTarget2D = Cast<UTextureRenderTarget2D>(SourceTexture);
 57         TextureResource = TextureRenderTarget2D->GameThread_GetRenderTargetResource();
 58     }
 59     check(TextureResource != nullptr);
 60 
 61     // Draw a quad to copy the texture over to the render target
 62     {
 63         const float MinU = 0.0f;
 64         const float MinV = 0.0f;
 65         const float MaxU = 1.0f;
 66         const float MaxV = 1.0f;
 67         const float MinX = 0.0f;
 68         const float MinY = 0.0f;
 69         const float MaxX = Width;
 70         const float MaxY = Height;
 71 
 72         FCanvasUVTri Tri1;
 73         FCanvasUVTri Tri2;
 74         Tri1.V0_Pos = FVector2D(MinX, MinY);
 75         Tri1.V0_UV = FVector2D(MinU, MinV);
 76         Tri1.V1_Pos = FVector2D(MaxX, MinY);
 77         Tri1.V1_UV = FVector2D(MaxU, MinV);
 78         Tri1.V2_Pos = FVector2D(MaxX, MaxY);
 79         Tri1.V2_UV = FVector2D(MaxU, MaxV);
 80 
 81         Tri2.V0_Pos = FVector2D(MaxX, MaxY);
 82         Tri2.V0_UV = FVector2D(MaxU, MaxV);
 83         Tri2.V1_Pos = FVector2D(MinX, MaxY);
 84         Tri2.V1_UV = FVector2D(MinU, MaxV);
 85         Tri2.V2_Pos = FVector2D(MinX, MinY);
 86         Tri2.V2_UV = FVector2D(MinU, MinV);
 87         Tri1.V0_Color = Tri1.V1_Color = Tri1.V2_Color = Tri2.V0_Color = Tri2.V1_Color = Tri2.V2_Color = FLinearColor::White;
 88         TArray< FCanvasUVTri > List;
 89         List.Add(Tri1);
 90         List.Add(Tri2);
 91         FCanvasTriangleItem TriItem(List, TextureResource);
 92         TriItem.BlendMode = SE_BLEND_Opaque;
 93         Canvas.DrawItem(TriItem);
 94     }
 95 
 96     // Tell the rendering thread to draw any remaining batched elements
 97     Canvas.Flush_GameThread(true);
 98 
 99     ENQUEUE_RENDER_COMMAND(UpdateMeshPaintRTCommand)(
100         [RenderTargetResource](FRHICommandListImmediate& RHICmdList)
101         {
102             // Copy (resolve) the rendered image from the frame buffer to its render target texture
103             RHICmdList.CopyToResolveTarget(
104                 RenderTargetResource->GetRenderTargetTexture(),        // Source texture
105                 RenderTargetResource->TextureRHI,                    // Dest texture
106                 FResolveParams());                                    // Resolve parameters
107         });
108 }
109 
110 //
111 bool URenderCineCameraLibrary::SaveRenderTargetToFile(UTextureRenderTarget2D* rt, const FString& fileDestination)
112 {
113     FTextureRenderTargetResource* rtResource = rt->GameThread_GetRenderTargetResource();
114     FReadSurfaceDataFlags readPixelFlags(RCM_UNorm);
115 
116     TArray<FColor> outBMP;
117     outBMP.AddUninitialized(rt->GetSurfaceWidth() * rt->GetSurfaceHeight());
118     rtResource->ReadPixels(outBMP, readPixelFlags);
119 
120 
121     IImageWrapperModule& ImageWrapperModule = FModuleManager::LoadModuleChecked<IImageWrapperModule>(FName("ImageWrapper"));
122     TSharedPtr<IImageWrapper> ImageWrapper = ImageWrapperModule.CreateImageWrapper(EImageFormat::JPEG);
123     ImageWrapper->SetRaw(outBMP.GetData(), outBMP.GetAllocatedSize(), rt->GetSurfaceWidth(), rt->GetSurfaceHeight(), ERGBFormat::BGRA, 8);
124 
125     const TArray64<uint8>& PNGData = ImageWrapper->GetCompressed(100);
126     bool imageSavedOk = FFileHelper::SaveArrayToFile(PNGData, *fileDestination);
127     ImageWrapper.Reset();
128 
129 
130     /*FIntPoint destSize(rt->GetSurfaceWidth(), rt->GetSurfaceHeight());
131     TArray<uint8> CompressedBitmap;
132     FImageUtils::CompressImageArray(destSize.X, destSize.Y, outBMP, CompressedBitmap);
133     bool imageSavedOk = FFileHelper::SaveArrayToFile(CompressedBitmap, *fileDestination);*/
134 
135     return imageSavedOk;
136 }

 

posted @ 2022-11-28 11:13  sev  阅读(798)  评论(0编辑  收藏  举报