언리얼에서는 스크린샷을 찍는 함수를 제공합니다. static 함수이므로 아래와 같이 호출하도록 합니다.
FScreenshotRequest::RequestScreenshot(TEXT(""), true, true);
아래는 함수 원본입니다. 파라미터로 파일명, SlateUI에 보여질 지 여부와 파일명에 자동으로 고유의 Suffix 붙일지 여부를 넘겨줍니다. 고유의 Suffix는 옵션에 따라 시간값을 지정하거나, 오름차순의 Index 값으로 지정됩니다.
/**
* Requests a new screenshot with a specific filename
*
* @param InFilename The filename to use
* @param bInShowUI Whether or not to show Slate UI
* @param bAddFilenameSuffix Whether an auto-generated unique suffix should be added to the supplied filename
*/
void FScreenshotRequest::RequestScreenshot(const FString& InFilename, bool bInShowUI, bool bAddUniqueSuffix)
{
FString GeneratedFilename = InFilename;
CreateViewportScreenShotFilename(GeneratedFilename);
if (bAddUniqueSuffix)
{
const bool bRemovePath = false;
GeneratedFilename = FPaths::GetBaseFilename(GeneratedFilename, bRemovePath);
if (GetHighResScreenshotConfig().bDateTimeBasedNaming)
{
FFileHelper::GenerateDateTimeBasedBitmapFilename(GeneratedFilename, TEXT("png"), Filename);
}
else
{
FFileHelper::GenerateNextBitmapFilename(GeneratedFilename, TEXT("png"), Filename);
}
}
else
{
Filename = GeneratedFilename;
if (FPaths::GetExtension(Filename).Len() == 0)
{
Filename += TEXT(".png");
}
}
// Register the screenshot
if (!Filename.IsEmpty())
{
bShowUI = bInShowUI;
bIsScreenshotRequested = true;
}
GScreenMessagesRestoreState = GAreScreenMessagesEnabled;
// Disable Screen Messages when the screenshot is requested without UI.
if (bInShowUI == false)
{
GAreScreenMessagesEnabled = false;
}
}
스크린샷을 찍은 후 콜백을 등록 할 수 있습니다.
UGameViewportClient::OnScreenshotCaptured().Clear();
UGameViewportClient::OnScreenshotCaptured().AddUObject(this, &UCaptureScreenshotPopup::OnScreenshotCaptured);
등록한 콜백에는 스크린샷의 가로, 세로 사이즈와 스크린샷 이미지가 파라미터로 전달됩니다.
콜백에서 전달받은 데이터를 이용해 스크린샷을 Texture로 변환하여 UI로 보여주는 등의 작업을 진행할 수 있습니다.
void UCaptureScreenshotPopup::OnScreenshotCaptured(int32 Width, int32 Height, const TArray<FColor>& Image)
{
SavedWidth = Width;
SavedHeight = Height;
SavedImage = Image;
CaptureTexture = UGeneralStatics::ConvertFColorArrayToTexture(Width, Height, Image);
if (nullptr == CaptureTexture || false == IsValid(IMG_Screenshot))
{
return;
}
IMG_Screenshot->SetBrushFromTexture(CaptureTexture, true);
}
FColor Array를 Texture로 변환하여 사용하도록 합니다.
UTexture2D* UGeneralStatics::ConvertFColorArrayToTexture(int32 Width, int32 Height, const TArray<FColor>& Image)
{
UTexture2D* CaptureTexture = UTexture2D::CreateTransient(Width, Height, PF_B8G8R8A8);
if (nullptr == CaptureTexture)
{
return nullptr;
}
if (nullptr == CaptureTexture->PlatformData)
{
return nullptr;
}
if (false == CaptureTexture->PlatformData->Mips.IsValidIndex(0))
{
return nullptr;
}
// Copy!
FTexture2DMipMap& Mip = CaptureTexture->PlatformData->Mips[0];
void* TextureData = Mip.BulkData.Lock(LOCK_READ_WRITE);
FMemory::Memcpy(TextureData, Image.GetData(), Image.Num() * 4);
Mip.BulkData.Unlock();
// Update!
CaptureTexture->UpdateResource();
return CaptureTexture;
}