file://E:/UE___Projects_Test/MyProjectAAA/Plugins/WXimage.jpg
build.cs 添加 ImageWrapper 模块,使用时注意添加相关头文件
PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "ImageWrapper" });
支持图片类型
注意 jpg 读取后 R 和 B 的通道位置
代码实现(4.26)
UENUM(BlueprintType)
enum class EImgFormat : uint8
{
/** Portable Network Graphics. */
PNG = 0,
/** Joint Photographic Experts Group. */
JPEG,
/** Single channel JPEG. */
GrayscaleJPEG,
/** Windows Bitmap. */
BMP,
/** Windows Icon resource. */
ICO,
/** OpenEXR (HDR) image file format. */
EXR,
/** Mac icon. */
ICNS
};
UTexture2D* ADataDriveActor::ImportImage(const FString& path, EImgFormat Type, bool& IsValid, int32& OutWidth, int32& OutHeight)
{
UTexture2D* Texture = nullptr;
IsValid = false;
// 文件是否存在
if (!FPlatformFileManager::Get().GetPlatformFile().FileExists(*path))
{
return nullptr;
}
// 图片是否加载
TArray<uint8> RawFileData;
if (!FFileHelper::LoadFileToArray(RawFileData, *path))
{
return nullptr;
}
IImageWrapperModule& ImageWrapperModule = FModuleManager::LoadModuleChecked<IImageWrapperModule>(FName("ImageWrapper"));
// 自定义枚举转换 EImageFormat
// IImageWrapperPtr 变更为 TSharedPtr<IImageWrapper>
TSharedPtr<IImageWrapper> ImageWrapper = ImageWrapperModule.CreateImageWrapper(static_cast<EImageFormat>((int8)Type));
if (ImageWrapper.IsValid() && ImageWrapper->SetCompressed(RawFileData.GetData(), RawFileData.Num()))
{
// 此处有所变动 低版本为 const TArray<uint8>* UncompressedRGBA = nullptr;
TArray<uint8> UncompressedRGBA ;
if (ImageWrapper->GetRaw(ERGBFormat::RGBA, 8, UncompressedRGBA))
{
Texture = UTexture2D::CreateTransient(ImageWrapper->GetWidth(), ImageWrapper->GetHeight(), PF_R8G8B8A8);
if (Texture != nullptr)
{
IsValid = true;
OutWidth = ImageWrapper->GetWidth();
OutHeight = ImageWrapper->GetHeight();
void* TextureData = Texture->PlatformData->Mips[0].BulkData.Lock(LOCK_READ_WRITE);
FMemory::Memcpy(TextureData, UncompressedRGBA.GetData(), UncompressedRGBA.Num());
Texture->PlatformData->Mips[0].BulkData.Unlock();
Texture->UpdateResource();
}
}
}
return Texture;
}
使用 mip.BulkData.Lock(LOCK_READ_WRITE) 前需要对Texture 设置一些参数,否则会返回 nullptr
代码实现
bool ADataDriveActor::ExportImage(UTexture2D* Texture2D, const FString& Path)
{
// setup required parameters
TextureCompressionSettings OldCompressionSettings = Texture2D->CompressionSettings;
TextureMipGenSettings OldMipGenSettings = Texture2D->MipGenSettings;
bool OldSRGB = Texture2D->SRGB;
Texture2D->CompressionSettings = TextureCompressionSettings::TC_VectorDisplacementmap;
Texture2D->MipGenSettings = TextureMipGenSettings::TMGS_NoMipmaps;
Texture2D->SRGB = false;
Texture2D->UpdateResource();
FTexture2DMipMap& mipmap = Texture2D->PlatformData->Mips[0];
uint8* Data = (uint8*)mipmap.BulkData.Lock(LOCK_READ_WRITE);
//FColor* FormatedImageData = static_cast<FColor*>(mipmap.BulkData.Lock(LOCK_READ_WRITE));
if (Data == nullptr)
{
mipmap.BulkData.Unlock(); // 不释放,会卡住
Texture2D->UpdateResource();
return false;
}
int width = Texture2D->PlatformData->SizeX;
int height = Texture2D->PlatformData->SizeY;
TArray<FColor> nColors;
for (int32 y = 0; y < height; y++)
{
for (int32 x = 0; x < width; x++)
{
FColor bColor;
bColor.B = Data[(y * width + x) * 4 + 0];//B 0 - 255
bColor.G = Data[(y * width + x) * 4 + 1];//G
bColor.R = Data[(y * width + x) * 4 + 2];//R
bColor.A = Data[(y * width + x) * 4 + 3];//A
nColors.Add(bColor);
}
}
mipmap.BulkData.Unlock();
// return old parameters
Texture2D->CompressionSettings = OldCompressionSettings;
Texture2D->MipGenSettings = OldMipGenSettings;
Texture2D->SRGB = OldSRGB;
Texture2D->UpdateResource();
//获取 uint8 数据,保存
TArray<uint8> ImgData;
FImageUtils::CompressImageArray(width, height, nColors, ImgData);
return FFileHelper::SaveArrayToFile(ImgData, *Path);
}
【UE4 C++】 外部图片读取、Texture 保存 png
原文:https://www.cnblogs.com/shiroe/p/14766534.html