Unreal 관련 자료는 이상하게 찾기가 힘든 거 같습니다...
이미지를 png로 저장하기 위해서 여러 삽질을 하다 보니 동작하는 코드를 찾아서 기록하게 되었습니다.
(Windows, Android 환경에서는 잘 동작하네요)
우선 UImage를 UTexture2D로 변경하는 과정이 필요한데, Brush의 ResourceObject를 가지고 와서 UTexture2D로 바꿔줄 수 있었습니다.
아래 공식 문서를 참고했습니다.
https://docs.unrealengine.com/4.27/en-US/API/Runtime/UMG/Components/UImage/
UTexture2D를 Color의 Array로 바꾸는 예시를 찾는 데도 좀 오래 걸렸는데 어찌하다 보니 잘 되네요
FFileHelper::SaveArrayToFile를 사용하기 위해서 Color의 Array로 변경해서 사용했습니다.
이미지를 저장할때 FPaths::ProjectPersistentDownloadDir() 이것을 사용했습니다.
Android 11 기기에서 파일 저장이 안 되는 경우가 있는데, 안드로이드의 다운로드 경로에 파일을 저장하면 정상 동작해서 해당 경로를 사용하게 되었습니다.
UPROPERTY(meta = (BindWidget))
class UImage* Image_Logo;
// UImage를 UTexture2D로 변환
FSlateBrush Brush = Image_Logo->Brush;
UTexture2D* texture = Cast<UTexture2D>( Brush.GetResourceObject() );
// 이미지 경로 (다운로드 경로를 이용한다)
// Android 일부 기기에서 Saved 같은 언리얼 엔진에서 사용하는 경로에 파일이 저장이 안되는 경우가 있는데
// 다운로드 경로를 사용하면 정상적으로 동작한다.
FString imagePath = FPaths::Combine(FPaths::ProjectPersistentDownloadDir(), TEXT("temp.png"));
// UTexture2D를 png로 저장하기
static bool SaveImage(UTexture2D* texture, const FString& path)
{
TArray<FColor> colors;
const FColor* FormatedImageData = static_cast<const FColor*>( texture->PlatformData->Mips[0].BulkData.LockReadOnly());
for (int32 Y = 0; Y < texture->GetSizeY(); Y++)
{
for (int32 X = 0; X < texture->GetSizeX(); X++)
{
FColor PixelColor = FormatedImageData[Y * texture->GetSizeX() + X];
colors.Add(PixelColor);
}
}
texture->PlatformData->Mips[0].BulkData.Unlock();
TArray<uint8> compressedBitmap;
FImageUtils::CompressImageArray(texture->GetSizeX(), texture->GetSizeY(), colors, compressedBitmap);
bool isSavedImage = FFileHelper::SaveArrayToFile(compressedBitmap, *path);
return isSavedImage;
}