BLOGブログ

2018.02.23UE4UE/ C++

ImageWrapperModuleを用いて指定の拡張子でスクリーンショットを書き出す方法

本日は、ImageWrapperModuleを用いて、スクリーンショットを、

指定の拡張子にて、書き出す方法をご紹介します。

 

スクリーンショットを撮る関数に関しては、以前ご紹介した記事を、

参考にしていただけると幸いです。

[UE4]BPで、HUD込みのスクリーンショットを取る方法

 

今回は、上記の関数に、ImageWapperを用いた部分を中心にご紹介します。

 

1.下準備

まずは、今回使用するImageWrapperModuleを、

プロジェクトの”プロジェクト名.Build.csの、PublicDependencyModuleNamesへ追加します。

これで、プロジェクト内で、ImageWrapperModuleを使用できるようになります。

 

2.ヘッダーでの下準備

ヘッダーにおける下準備は、下記の4点になります。

A. class IImageWrapperModuleの追加。

B. 拡張子選択用UENUMの作成

C. 使用する変数の宣言

D. 関数の宣言

 

それでは順番にみていきます。

A. class IImageWrapperModuleの追加。

クラス内でImageWapperModuleを使用するため、

まずはclass IImageWrapperModuleを追加します。

B. 拡張子選択用UENUMの作成
ImageWrapperModuleの中に、拡張子選択用のenum classがあるのですが、
UENUMとして書かれていないので、そのままではブループリントで使用できません。
ですので、ImageWrapperModule内のenum classを参考に、UENUM(BlueprintType)として、作成します。

今回は、PNG、JPEG、EXR形式へ、変換できるようにします。

/** Joint Photographic Experts Group. */
JPEG,

/** OpenEXR (HDR) image file format. */
EXR = 5,
};

これで、今回作成するImageWrapperModuleで使用されているのと同じ内容の、
UENUM(BlueprintType)が出来ました。

C. 使用する変数の宣言
関数内で使用する変数を、宣言します。

D. 関数の宣言
本題の、ImageWrapperを使用する関数を宣言します。
関数名は、今回はOnScreenshotCapturedInternalとしています。

また、スクリーンショットをとる、TakeScreenShot関数に、
今回追加された、format、quality変数へ渡すための引数を追加します。

_formatと、_qualityを追加しました。

ヘッダーの準備は以上になります。

3. cppファイルでの下準備
A. インクルードファイルの追加

B. ヘッダーで宣言した変数の追加

Ç. OnScreenshotCapturedInternal関数の定義

D.  TakeScreenShot関数の修正

それでは順番にみていきます。
A. インクルードファイルの追加
下記3つのインクルードファイルを追加します。

B. ヘッダーで宣言した変数の追加

Ç. OnScreenshotCapturedInternal関数の定義

fileName += “.png”;
FFileHelper::SaveArrayToFile(PNGData, *fileName);
}
else if (format == EImageFormatType::JPEG)
{
ImageWrapper = ImageWrapperModule.CreateImageWrapper(EImageFormat::JPEG);
ImageWrapper->SetRaw(Bitmap.GetData(), Bitmap.GetAllocatedSize(), Width, Height, ERGBFormat::BGRA, 8);
const TArray& JPEGData = ImageWrapper->GetCompressed(quality);
fileName += “.jpg”;
FFileHelper::SaveArrayToFile(JPEGData, *fileName);
}
else if (format == EImageFormatType::EXR)
{
ImageWrapper = ImageWrapperModule.CreateImageWrapper(EImageFormat::EXR);
ImageWrapper->SetRaw(Bitmap.GetData(), Bitmap.GetAllocatedSize(), Width, Height, ERGBFormat::BGRA, 8);
const TArray& Data = ImageWrapper->GetCompressed(quality);
fileName += “.exr”;
FFileHelper::SaveArrayToFile(Data, *fileName);
}
else
{
//未定義の画像形式はJPEGでかき出し
ImageWrapper = ImageWrapperModule.CreateImageWrapper(EImageFormat::JPEG);
ImageWrapper->SetRaw(Bitmap.GetData(), Bitmap.GetAllocatedSize(), Width, Height, ERGBFormat::BGRA, 8);
const TArray& JPEGData = ImageWrapper->GetCompressed(quality);
fileName += “.jpg”;
FFileHelper::SaveArrayToFile(JPEGData, *fileName);
}
UGameViewportClient::OnScreenshotCaptured().Remove(delegateHandle);
ImageWrapper.Reset();

#endif
}

この関数の中で、受け取った画像データを、指定の拡張子のデータに変換します。

D.  TakeScreenShot関数の修正
TakeScreenShot関数を、OnScreenshotCapturedInternal関数を組み込む形で、
修正をします。

format = _format;
quality = _quality;

//現在時刻でスクリーンショットに名前をつける
if (bInsertTimeStampToFileName)
{
filename += “_” + FDateTime::Now().ToString();
}
//ユニークID付きの時はID前に_を付加
if (bAddFilenameSuffix)
{
filename += “_”;
}

UTalkCameraFunctionLibrary::fileName = FPaths::ProjectSavedDir() + “ScreenShots/Windows/” + filename;

if (!UGameViewportClient::OnScreenshotCaptured().IsBound())
{
delegateHandle = UGameViewportClient::OnScreenshotCaptured().AddStatic(&UTalkCameraFunctionLibrary::OnScreenshotCapturedInternal);//今回の追加分。
FScreenshotRequest::RequestScreenshot(filename, bInShowUI, bAddFilenameSuffix);
}

#endif
}

4. レベルブループリントでテスト
作成した関数を、レベルブループリントで、任意のキーを割り当てて、テストをしてみましょう。

今回はPを押すと、スクリーンショットを撮るようにしました。

Formatを、JPEGにしてあります。

 

無事に、JPEG画像として、書き出すことが出来ました。

 

今回は、エンジンバージョン4.18.3で作成していますが、

古いバージョンでは、同じ内容で記述しても、動かないことがありますので、

ご注意の上お試しください。