增加自定义hdr图展示功能

This commit is contained in:
liuyunhui
2026-03-05 11:33:15 +08:00
parent e1f629f2ac
commit 836b65a737
23 changed files with 212 additions and 29 deletions
@@ -131,3 +131,136 @@ float UMyBlueprintFunctionLibrary::GetSystemVolume()
{
return _GetSystemVolume();
}
#include "IImageWrapperModule.h"
#include "Misc/FileHelper.h"
#include "Misc/Paths.h"
#include "Engine/Texture2D.h"
#include "HAL/FileManagerGeneric.h"
bool UMyBlueprintFunctionLibrary::LoadImagesFromFolder(
const FString& FolderPath,
TArray<FString>& OutImageNames,
TArray<UTexture2D*>& OutTextures,
bool bRecursive
)
{
// 清空输出数组(避免残留数据)
OutImageNames.Empty();
OutTextures.Empty();
// 1. 校验文件夹路径有效性
if (!FPaths::DirectoryExists(FolderPath))
{
UE_LOG(LogTemp, Error, TEXT("图片文件夹不存在:%s"), *FolderPath);
return false;
}
// 2. 获取文件夹下所有图片文件(支持常见格式:png/jpg/jpeg/bmp
TArray<FString> ImageFilePaths;
const FString FileExtensionFilter = TEXT("*");
IFileManager& FileManager = IFileManager::Get();
FileManager.FindFiles(ImageFilePaths, *FolderPath, *FileExtensionFilter);
if (ImageFilePaths.Num() == 0)
{
UE_LOG(LogTemp, Warning, TEXT("文件夹下未找到图片文件:%s"), *FolderPath);
return true; // 无文件不算错误,返回true
}
// 3. 遍历加载每张图片
for (const FString& ImageFilePath : ImageFilePaths)
{
// 加载图片为Texture2D
UTexture2D* Texture = LoadSingleImageToTexture(FPaths::Combine(FolderPath,ImageFilePath));
if (Texture)
{
// 获取图片名称(不含路径和扩展名)
FString ImageName = FPaths::GetBaseFilename(ImageFilePath);
OutImageNames.Add(ImageName);
OutTextures.Add(Texture);
UE_LOG(LogTemp, Log, TEXT("成功加载图片:%s → Texture%s"), *ImageFilePath, *Texture->GetName());
}
else
{
UE_LOG(LogTemp, Error, TEXT("加载图片失败:%s"), *ImageFilePath);
}
}
return OutTextures.Num() > 0;
}
UTexture2D* UMyBlueprintFunctionLibrary::LoadSingleImageToTexture(const FString& ImageFilePath)
{
// 1. 读取图片文件二进制数据
TArray<uint8> ImageFileData;
if (!FFileHelper::LoadFileToArray(ImageFileData, *ImageFilePath))
{
UE_LOG(LogTemp, Error, TEXT("读取图片文件失败:%s"), *ImageFilePath);
return nullptr;
}
// 2. 获取ImageWrapper模块(用于解析图片数据)
IImageWrapperModule& ImageWrapperModule = FModuleManager::LoadModuleChecked<IImageWrapperModule>(TEXT("ImageWrapper"));
TSharedPtr<IImageWrapper> ImageWrapper;
// 根据扩展名选择对应的解析器
const FString FileExtension = FPaths::GetExtension(ImageFilePath).ToLower();
if (FileExtension == TEXT("png"))
{
ImageWrapper = ImageWrapperModule.CreateImageWrapper(EImageFormat::PNG);
}
else if (FileExtension == TEXT("jpg") || FileExtension == TEXT("jpeg"))
{
ImageWrapper = ImageWrapperModule.CreateImageWrapper(EImageFormat::JPEG);
}
else if (FileExtension == TEXT("bmp"))
{
ImageWrapper = ImageWrapperModule.CreateImageWrapper(EImageFormat::BMP);
}
else
{
UE_LOG(LogTemp, Error, TEXT("不支持的图片格式:%s"), *FileExtension);
return nullptr;
}
// 3. 解析图片数据为RGB格式
if (!ImageWrapper.IsValid() || !ImageWrapper->SetCompressed(ImageFileData.GetData(), ImageFileData.Num()))
{
UE_LOG(LogTemp, Error, TEXT("解析图片数据失败:%s"), *ImageFilePath);
return nullptr;
}
TArray<uint8> RawImageData;
if (!ImageWrapper->GetRaw(ERGBFormat::RGBA, 8, RawImageData))
{
UE_LOG(LogTemp, Error, TEXT("转换图片为RGBA数据失败:%s"), *ImageFilePath);
return nullptr;
}
// 4. 创建并初始化Texture2D
UTexture2D* Texture = UTexture2D::CreateTransient(
ImageWrapper->GetWidth(),
ImageWrapper->GetHeight(),
PF_R8G8B8A8 // 像素格式(RGBA8位)
);
if (!Texture)
{
UE_LOG(LogTemp, Error, TEXT("创建Texture2D失败:%s"), *ImageFilePath);
return nullptr;
}
// 5. 将图片数据写入Texture
void* TextureData = Texture->GetPlatformData()->Mips[0].BulkData.Lock(LOCK_READ_WRITE);
FMemory::Memcpy(TextureData, RawImageData.GetData(), RawImageData.Num());
Texture->GetPlatformData()->Mips[0].BulkData.Unlock();
// 6. 设置Texture属性并更新
Texture->SRGB = true; // 图片默认开启SRGB(非UI/法线贴图需关闭)
#undef UpdateResource // 取消Windows宏干扰
Texture->UpdateResource();
return Texture;
}
@@ -18,4 +18,25 @@ class SPACESTUDIOCLIENT_API UMyBlueprintFunctionLibrary : public UBlueprintFunct
UFUNCTION(BlueprintCallable, Category = "MyLibrary|Sound", meta = (DisplayName = "get system volume"))
static float GetSystemVolume();
public:
/**
* 加载指定文件夹下的所有图片并生成Texture2D
* @param FolderPath 文件夹路径(支持绝对路径/项目相对路径,如 "/Game/Textures/MyImages" 或 "D:/Images/"
* @param OutImageNames 输出:图片名称数组(不含扩展名)
* @param OutTextures 输出:生成的Texture2D数组
* @param bRecursive 是否递归加载子文件夹
* @return 是否加载成功
*/
UFUNCTION(BlueprintCallable, Category = "ImageLoader")
static bool LoadImagesFromFolder(
const FString& FolderPath,
TArray<FString>& OutImageNames,
TArray<UTexture2D*>& OutTextures,
bool bRecursive = false
);
private:
// 内部辅助函数:加载单张图片为Texture2D
static UTexture2D* LoadSingleImageToTexture(const FString& ImageFilePath);
};
@@ -8,7 +8,7 @@ public class SpaceStudioClient : ModuleRules
{
PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;
PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore" });
PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "ImageWrapper" });
PrivateDependencyModuleNames.AddRange(new string[] { });