if (!FPaths::FileExists(FilePath))
{
UE_LOG(LogTemp, Error, TEXT("File not found: %s"), *FilePath);
return nullptr;
}
// Load the compressed byte data from the file
TArray<uint8> FileData;
if (!FFileHelper::LoadFileToArray(FileData, *FilePath))
{
UE_LOG(LogTemp, Error, TEXT("Failed to load file: %s"), *FilePath);
return nullptr;
}
// Detect the image type using the ImageWrapper module
IImageWrapperModule& ImageWrapperModule = FModuleManager::LoadModuleChecked<IImageWrapperModule>(TEXT("ImageWrapper"));
EImageFormat::Type ImageFormat = ImageWrapperModule.DetectImageFormat(FileData.GetData(), FileData.Num());
if (ImageFormat == EImageFormat::Invalid)
{
UE_LOG(LogTemp, Error, TEXT("Unrecognized image file format: %s"), *FilePath);
return nullptr;
}
// Create an image wrapper for the detected image format
IImageWrapperPtr ImageWrapper = ImageWrapperModule.CreateImageWrapper(ImageFormat);
if (!ImageWrapper.IsValid())
{
UE_LOG(LogTemp, Error, TEXT("Failed to create image wrapper for file: %s"), *FilePath);
return nullptr;
}
// Decompress the image data
const TArray<uint8>* RawData = nullptr;
ImageWrapper->SetCompressed(FileData.GetData(), FileData.Num());
ImageWrapper->GetRaw(ERGBFormat::BGRA, 8, RawData);
if (RawData == nullptr)
{
UE_LOG(LogTemp, Error, TEXT("Failed to decompress image file: %s"), *FilePath);
return nullptr;
}
// Create the texture and upload the uncompressed image data
FString TextureBaseName = TEXT("Texture_") + FPaths::GetBaseFilename(FilePath);
// UObject* Outer = nullptr;
UTexture2D* mytexture = MyCreateTexture(*RawData, ImageWrapper->GetWidth(), ImageWrapper->GetHeight(), EPixelFormat::PF_B8G8R8A8, FName(*TextureBaseName));
return mytexture;
UTexture2D* SDrawHouseTypeTools::MyCreateTexture(const TArray<uint8>& PixelData, int32 InSizeX, int32 InSizeY, EPixelFormat InFormat, FName BaseName)
{
// Shamelessly copied from UTexture2D::CreateTransient with a few modifications
if (InSizeX <= 0 || InSizeY <= 0 ||
(InSizeX % GPixelFormats[InFormat].BlockSizeX) != 0 ||
(InSizeY % GPixelFormats[InFormat].BlockSizeY) != 0)
{
//UIL_LOG(Warning, TEXT("Invalid parameters specified for UImageLoader::CreateTexture()"));
return nullptr;
}
// Most important difference with UTexture2D::CreateTransient: we provide the new texture with a name and an owner
#if 0
FName TextureName = MakeUniqueObjectName(Outer, UTexture2D::StaticClass(), BaseName);
#endif
UTexture2D* NewTexture = NewObject<UTexture2D>(GetTransientPackage(), NAME_None, RF_Transient);
NewTexture->PlatformData = new FTexturePlatformData();
NewTexture->PlatformData->SizeX = InSizeX;
NewTexture->PlatformData->SizeY = InSizeY;
NewTexture->PlatformData->PixelFormat = InFormat;
// Allocate first mipmap and upload the pixel data
int32 NumBlocksX = InSizeX / GPixelFormats[InFormat].BlockSizeX;
int32 NumBlocksY = InSizeY / GPixelFormats[InFormat].BlockSizeY;
FTexture2DMipMap* Mip = new(NewTexture->PlatformData->Mips) FTexture2DMipMap();
Mip->SizeX = InSizeX;
Mip->SizeY = InSizeY;
Mip->BulkData.Lock(LOCK_READ_WRITE);
void* TextureData = Mip->BulkData.Realloc(NumBlocksX * NumBlocksY * GPixelFormats[InFormat].BlockBytes);
FMemory::Memcpy(TextureData, PixelData.GetData(), PixelData.Num());
Mip->BulkData.Unlock();
NewTexture->UpdateResource();
return NewTexture;
}