画像ファイルを保存する際に利用するCLSIDの値をファイルの拡張子によって取得するには、GetImageEncoders関数を使います。
ビットマップオブジェクトの保存
例えば、次のようなBitmapを作って保存する場合に引数として画像ファイルのCLSIDが必要になることがあります。
Bitmap* pBitmap = new Bitmap(nWidth, nHeight);
Graphics* pGraphics = Graphics::FromImage ( pBitmap );
//省略
CLSID encoderClsid;
pBitmap->Save("保存する画像ファイル名", &encoderClsid);
あらかじめレジストリから、取得しておいてファイルの拡張子の条件分岐してCLSIDの変数に代入することもできますが、画像フォーマットが増えた場合に対応できなくなります。
GetImageEncoders関数で取得
ファイルの拡張子に応じて、CLSIDの値を取得する関数としてGetImageEncodersがあります。VC++で使うにはGDI+のヘッダーファイルをインクルードしておく必要があります。
#include <Gdiplus.h>
using namespace Gdiplus;
利用方法としては、ImageCodecInfo型の構造体変数を作成して、GetImageEncoders関数を使って取得し、構造体ないの.Clsid値から拡張子に応じたCLSIDを得ることができます。
関数化したコードはこんな感じ。
int GetEncoderClsid(const WCHAR* format, CLSID* pClsid)
{
UINT num = 0;
UINT size = 0;
ImageCodecInfo* pImageCodecInfo = NULL;
GetImageEncodersSize(&num, &size);
if(size == 0)
{
return -1; // 失敗 - GetImageEncodersSize 失敗
}
pImageCodecInfo = (ImageCodecInfo*)(malloc(size));
if(pImageCodecInfo == NULL)
{
return -1; // 失敗 - メモリ割り当て不可
}
GetImageEncoders(num, size, pImageCodecInfo);
for(UINT j = 0; j < num; ++j)
{
if( wcscmp(pImageCodecInfo[j].MimeType, format) == 0 )
{
*pClsid = pImageCodecInfo[j].Clsid;
free(pImageCodecInfo);
return j; // 成功
}
}
free(pImageCodecInfo);
return -1; // 失敗
}
実際に呼び出す側のコードはこんな感じになります。
// イメージの保存
CLSID encoderClsid;
CString sFileName = "ファイル名";
int nExtIndex = sFileName.ReverseFind('.');
CString sExtName = sFileName.Right(sFileName.GetLength() - nExtIndex - 1);
sExtName.MakeLower();
CString sEncode;
sEncode.Format("image/%s", sExtName);
if(GetEncoderClsid(A2W(sEncode), &encoderClsid) == -1)
{
//エラー
}
// Bitmap オブジェクトをファイルに保存。
pBitmap->Save(A2W(sFileName), &encoderClsid);
まとめ
GetImageEncoder関数を使うことで、ファイルの拡張子に応じたマシン内のCLSIDを取得することができます。
もちろん、あらかじめ取得しておいたCLSIDの値を、ファイルの拡張子を条件に分岐して、それぞれ代入するコードもありですが、拡張子が増えた場合など、コードのメンテナンス性を考えると、選択しにくいやり方です。
GetImageEncoder関数を使えば、拡張子に応じたCLSID値を取得することができるので、より汎用性の高い画像保存に関する処理にすることが出来るようになります。
スポンサーリンク
最後までご覧いただき、ありがとうございます。