To save you reinventing the wheel, check out the C++ source for Rama’s Extra Blueprint nodes.
It includes saving/loading textures, including textures from scene capture components.
I modified the function a bit.
The issue is that the texture settings must be set properly for the export.
-No Compression
-No Mipmaps
The function changes the settings of the texture temporarly.
void SaveTextureToDisk(UTexture2D* texture, const FString& file)
{
// Here I tried to work with a temporary texture, but that did not work. Changing the settings
// of the texture after copy did not have effect.
//UTexture2D* tempTex = texture->CreateTransient(texture->GetSizeX(), texture->GetSizeY());
//void* dest = tempTex->PlatformData->Mips[0].BulkData.Lock(LOCK_READ_WRITE);
//texture->PlatformData->Mips[0].BulkData.GetCopy(&dest, false);
//tempTex->PlatformData->Mips[0].BulkData.Unlock();
//tempTex->CompressionSettings = TextureCompressionSettings::TC_VectorDisplacementmap;
//tempTex->MipGenSettings = TextureMipGenSettings::TMGS_NoMipmaps;
//tempTex->UpdateResource();
TextureCompressionSettings prevCompression = texture->CompressionSettings;
TextureMipGenSettings prevMipSettings = texture->MipGenSettings;
texture->CompressionSettings = TextureCompressionSettings::TC_VectorDisplacementmap;
texture->MipGenSettings = TextureMipGenSettings::TMGS_NoMipmaps;
texture->UpdateResource();
FTexture2DMipMap* MM = &texture->PlatformData->Mips[0];
TArray<FColor> OutBMP;
int w = MM->SizeX;
int h = MM->SizeY;
OutBMP.SetNumUninitialized(w*h);
FByteBulkData* RawImageData = &MM->BulkData;
FColor* FormatedImageData = static_cast<FColor*>(RawImageData->Lock(LOCK_READ_ONLY));
if (FormatedImageData)
{
for (int i = 0; i < (w*h); ++i)
{
OutBMP* = FormatedImageData*;
OutBMP*.A = 255;
}
RawImageData->Unlock();
FIntPoint DestSize(w, h);
FString ResultPath;
FHighResScreenshotConfig& HighResScreenshotConfig = GetHighResScreenshotConfig();
HighResScreenshotConfig.SaveImage(file, OutBMP, DestSize, nullptr);
}
else
{
UE_LOG(LogTemp, Error, TEXT("SaveTextureToDisk: could not access bulk data of texture! Texture: %s"), *texture->GetFullName());
}
texture->CompressionSettings = prevCompression;
texture->MipGenSettings = prevMipSettings;
}
Hi! Rumbleball solution does not work in packaged game because UTexture::MipGenSettings is editor-only data.
Besides, BulkData size is different between cooked and non-cooked data…
How can I extract texture pixel array for cooked UTexture?
Thank you!
Links are working correctly. You must be logged into GitHub, and your GitHub account must be linked with your Epic Games account. Follow instruction here: Unreal Engine on GitHub - Unreal Engine