I’m trying to save a given UTexture2D as png. Current code works fine on Windows and in editor.
But when compiled for device, the for loop crashes the app. In some cases it writes a garbled png file.
I think this has something to do with using ASTC as the texture format. While reading the raw data I think the compressed code is being sent to me and not the raw data.
So, the for loop crash or wrong colors from the byte array.
What is the correct way of getting uncompressed bulk data on android for ASTC formatted textures in UE4?
Here is the code I’m currently using:
void UHitMeSingleton::Texture2DToPNG(UTexture2D* Texture, FString FileName, bool& IsValid) {
IsValid = false;
{
bool isOK = UCaller::CreateDataFolder();
if (!isOK) return;
}
if (!Texture) return;
#if WITH_EDITOR
Texture->MipGenSettings = TMGS_NoMipmaps;
#endif
Texture->SRGB = false;
Texture->CompressionSettings = TC_VectorDisplacementmap;
Texture->UpdateResource();
FTexture2DMipMap& CurrentMipMap = Texture->PlatformData->Mips[0];
int32 TextureWidth = CurrentMipMap.SizeX;
int32 TextureHeight = CurrentMipMap.SizeY;
if (TextureWidth <= 0 || TextureHeight <= 0) return;
FColor* RawColorArray = static_cast<FColor*>(Texture->PlatformData->Mips[0].BulkData.Lock(LOCK_READ_ONLY));
if (!RawColorArray) return;
TArray<FColor> PixelArray;
FColor PixelColor;
for (int32 y = 0; y < TextureHeight; y++) {
for (int32 x = 0; x < TextureWidth; x++) {
PixelColor = RawColorArray[y * TextureWidth + x];
PixelArray.Add(PixelColor);
}
}
Texture->PlatformData->Mips[0].BulkData.Unlock();
Texture->UpdateResource();
{
IImageWrapperModule& ImageWrapperModule = FModuleManager::LoadModuleChecked<IImageWrapperModule>(FName("ImageWrapper"));
IImageWrapperPtr ImageWrapper = ImageWrapperModule.CreateImageWrapper(EImageFormat::PNG);
bool rawOk = ImageWrapper->SetRaw(RawColorArray, PixelArray.Num() * sizeof(FColor), TextureWidth, TextureHeight, ERGBFormat::BGRA, 8);
if (rawOk) {
FString FullFilePath = UCaller::LocalDataImageFolder() + "/" + FileName + ".png";
IsValid = FFileHelper::SaveArrayToFile(ImageWrapper->GetCompressed(), *FullFilePath);
}
}
}