c++ UnrealEngine -如何从内存映像中获取缓冲区

kb5ga3dv  于 2023-03-10  发布在  其他
关注(0)|答案(1)|浏览(189)

在UnrealEngine的一个c++类中,我有一个运行时生成的PNG图像,我需要将其存储在缓冲区中,以便稍后转换为纹理。
我遗漏的是从内存中的PNG图像到TArray缓冲区的步骤(下面代码中的ima_buf)。

texture = FImageUtils::ImportBufferAsTexture2D(ima_buf);
6yoyoihd

6yoyoihd1#

注意:这段代码很大程度上是基于拉马的代码,Rama是Unreal Forums著名的用户和引擎贡献者
如果你有一个图像作为缓冲区,并且缓冲区在TArray<uint8>中,下面是函数。

#include "ImageUtils.h"
#include "IImageWrapper.h"
#include "IImageWrapperModule.h"

// in some class USomeClassOfYours (replace with needed name)
    static UTexture2D* LoadTexture2D_FromBuffer(const TArray<uint8>& RawFileData, EImageFormat ImageFormat, bool& IsValid, int32& Width, int32& Height);

在.cpp中

UTexture2D* USomeClassOfYours::LoadTexture2D_FromBuffer(const TArray<uint8>& RawFileData, EImageFormat ImageFormat, bool& IsValid, int32& Width, int32& Height)
{
    IsValid = false;
    UTexture2D* LoadedT2D = nullptr;
    
    IImageWrapperModule& ImageWrapperModule = FModuleManager::LoadModuleChecked<IImageWrapperModule>(FName("ImageWrapper"));
    TSharedPtr<IImageWrapper> ImageWrapper = ImageWrapperModule.CreateImageWrapper(ImageFormat);
 
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      
    //Create T2D!
    if (ImageWrapper.IsValid() && ImageWrapper->SetCompressed(RawFileData.GetData(), RawFileData.Num()))
    { 
        TArray<uint8> UncompressedBGRA;
        if (ImageWrapper->GetRaw(ERGBFormat::BGRA, 8, UncompressedBGRA))
        {
            LoadedT2D = UTexture2D::CreateTransient(ImageWrapper->GetWidth(), ImageWrapper->GetHeight(), PF_B8G8R8A8);
            
            //Valid?
            if(!LoadedT2D) return nullptr;
            //~~~~~~~~~~~~~~
            
            //Out!
            Width = ImageWrapper->GetWidth();
            Height = ImageWrapper->GetHeight();
             
            //Copy!
            void* TextureData = LoadedT2D->PlatformData->Mips[0].BulkData.Lock(LOCK_READ_WRITE);
            FMemory::Memcpy(TextureData, UncompressedBGRA.GetData(), UncompressedBGRA.Num());
            LoadedT2D->PlatformData->Mips[0].BulkData.Unlock();

            //Update!
            LoadedT2D->UpdateResource();
        }
    }
     
    // Success!
    IsValid = true;
    return LoadedT2D;
}

如果你需要从文件导入,添加第二个函数,它将使用上面的函数。

/** Load a Texture2D from a JPG,PNG,BMP,ICO,EXR,ICNS file! IsValid tells you if file path was valid or not. Enjoy! -Rama */
    static UTexture2D* LoadTexture2D_FromFile(const FString& FullFilePath, EImageFormat ImageFormat, bool& IsValid, int32& Width, int32& Height);

和.cpp

UTexture2D* USomeClassOfYours::LoadTexture2D_FromFile(const FString& FullFilePath, EImageFormat ImageFormat, bool& IsValid, int32& Width, int32& Height)
{ 
    //Load From File
    TArray<uint8> RawFileData;
    if (!FFileHelper::LoadFileToArray(RawFileData, *FullFilePath)) return nullptr;
    
    return LoadTexture2D_FromBuffer(RawFileData, ImageFormat, IsValid, Width, Height);
}

对于.png图像,当然应该使用EImageFormat::PNG作为格式输入变量。

相关问题