画像を保存
処理が完了した画像を保存するには、IWICBitmapEncoderを利用する。
IWICBitmapEncoderのインスタンス作成時には、WIC GUIDs and CLSIDsにあるGUID_ContainerFormat*の中から、自分が使いたいフォーマットのエンコーダを選択する。
// TIFFエンコーダを作成 CComPtr<IWICBitmapEncoder> encoder; imagingFactory->CreateEncoder(GUID_ContainerFormatTiff, NULL, &encoder);
次に、書き出し先のIStreamが必要になるが、これは、適宜、作成し、IWICBitmapEncoder::Initializeに渡して初期化する。
// output.tifに書き出す CComPtr<IStream> stream; // SHCreateStreamOnFile(_T("output.tif"), STGM_WRITE, &stream); SHCreateStreamOnFileEx(_T("output.tif"), STGM_WRITE | STGM_FAILIFTHERE, 0, TRUE, NULL, &stream); encoder->Initialize(stream, WICBitmapEncoderNoCache);
画像自体は、読み込み時と同様、フレームという単位で書き込む。TIFFだと複数ページを保存できるので、フレームを複数持つことができる。その他の画像フォーマットでは、1つのみ。いずれにしても、このフレームは、IWICBitmapEncoder::CreateNewFrameで行う。
// フレーム(ページ)を追加
CComPtr<IWICBitmapFrameEncode> frameEncode;
CComPtr<IPropertyBag2> propBag;
encoder->CreateNewFrame(&frameEncode, &propBag);
このとき、一緒に、IPropertyBag2のインスタンスが取得できるが、エンコードの品質などを設定しない場合には何もしなく良い。このインスタンスを、IWICBitmapEncoder::Initializeに直接渡すことによって、デフォルトの設定を利用できる。
// デフォルトの設定でエンコーダを初期化
frameEncode->Initialize(propBag);
IWICBitmapFrameEncodeに対しては、IWICBitmapFrameEncode::WriteSourceを呼び出して、すでに持っているIWICBitmapSourceのインスタンスを渡せばよい。ここでは、上記のサンプルでsRGBに変換した画像をそのまま利用する。
UINT width, height; transform->GetSize(&width, &height); frameEncode->SetSize(width, height); GUID fmtOut = GUID_WICPixelFormat24bppBGR; frameEncode->SetPixelFormat(&fmtOut); WICRect rcSave = {0, 0, width, height}; frameEncode->WriteSource(transform, &rcSave); frameEncode->Commit(); frameEncode = NULL; // もう必要ないので解放
最後には、IWICBitmapEncoder::Commitを呼び出して作業終了。
// 作成終了 encoder->Commit(); encoder = NULL; // もう必要ないので解放