- ベストアンサー
WindowsAPIで画像フォーマットの変換
Visual C++上でプログラムを作っています。 RGBA(32bit)の画像データを、RGB565(16bit)に変換したいのですが、このようなフォーマット変換を自動的に行ってくれるAPIは存在するでしょうか?
- みんなの回答 (1)
- 専門家の回答
質問者が選んだベストアンサー
こんにちは。 こう言った類の変換を容易に引き受けてくれるwin32APIは存在しません。 RGB565のビットマップを以下で作成して http://msdn.microsoft.com/ja-jp/library/cc428334.aspx 以下のAPIでRGB565に向かって描写すれば変換が出来ます。 http://msdn.microsoft.com/ja-jp/library/cc428307.aspx 但し、気をつけなければ成らないのが、win32APIはアルファチャンネル付を受け付けていないので、事前にアルファチャンネルを剥がしてRGBA8888(32bit)からRGB888(32bit)に変換しておきます。 手順としては、RGBA(32bit)→RGB(32bit)→RGB565(16bit)となります。 #include<windows.h> #include<tchar.h> //ビットマップヘッダの初期化 static void InitHDR(LPBITMAPINFOHEADER p, long w, long h) { p->biSize = sizeof(*p); p->biPlanes = 1; p->biBitCount = 16; p->biCompression = BI_BITFIELDS; p->biWidth = w; p->biHeight= h; } //RGB565フィールドの設定 static void InitFields(DWORD f[]) { f[0] = 0xf800; f[1] = 0x07e0; f[2] = 0x001f; } //変換 static HBITMAP Convert(HBITMAP hSrc) { if(!hSrc)return NULL; //hSrcから情報を取り出す BITMAP bitmap = {0}; ::GetObject(hSrc, sizeof(bitmap), &bitmap); //RGB565の作成 HGLOBAL hMem = ::GlobalAlloc(GMEM_ZEROINIT | GMEM_FIXED, sizeof(BITMAPFILEHEADER) + (sizeof(DWORD) * 3)); LPBITMAPINFO p = static_cast<LPBITMAPINFO>(::GlobalLock(hMem)); ::InitHDR(&p->bmiHeader, bitmap.bmWidth, bitmap.bmHeight); ::InitFields(reinterpret_cast<LPDWORD>(p->bmiColors)); LPVOID pvBits = NULL; HBITMAP h565 = ::CreateDIBSection(NULL, p, DIB_RGB_COLORS, &pvBits, NULL, 0); //デバイスコンキスト作成 HDC hDC565 = ::CreateCompatibleDC(NULL); HDC hDCSrc = ::CreateCompatibleDC(NULL); HGDIOBJ h565Prev = ::SelectObject(hDC565, h565); HGDIOBJ hSrcPrev = ::SelectObject(hDCSrc, hSrc); //RGB565へ転送して変換する ::BitBlt(hDC565, 0, 0, bitmap.bmWidth, bitmap.bmHeight, hDCSrc, 0, 0, SRCCOPY); ::SelectObject(hDC565, h565Prev); ::SelectObject(hDCSrc, hSrcPrev); //後始末 ::DeleteDC(hDC565); ::DeleteDC(hDCSrc); ::GlobalUnlock(hMem); ::GlobalFree(hMem); return h565; } int main() { //hbmp32はアルファチャンネルを剥がしたビットマップでなければ成らない HBITMAP hbmp16 = ::Convert(hbmp32); return 0; } 非常に面倒なので、GDI+をダウンロードして使用した方が賢明かもしれません。 http://msdn.microsoft.com/ja-jp/library/aa984108(VS.71).aspx
お礼
コードまで提示していただいて、ありがとうございます。CreateDIBSectionとBitBltを使って無事解決することができました。565フィールドの設定方法も大変参考になりました。