|
ビットマップからリージョンを作る |
![]() |
ビットマップからリージョンを作成するには様々な方法が提案されていますが、 どの方法を選択するにしても、ある程度長いプログラムになってしまうことは避けられません。 直接ビットマップからリージョンを作成する方法がないため仕方がないところです。 今回、このビットマップリージョンの解説のため、左の画像を使用します。 画像の著作権(pochi.gif / pochi.bmp) かねき 富士塗料店 / Kaneki Fuji Paint Store http://www5a.biglobe.ne.jp/~lowning8/index.htm |
| ダウンロード : ビットマップリージョンサンプル(2005/11/03) |
|
// ------------------------------------------------------------------ // ビットマップ形状に合わせてリージョンを作成する // ------------------------------------------------------------------ HRGN CtestBitmapRgnDlg::CreateRgnFromBitmap(HBITMAP hBitmap, DWORD dwTransColor) { // リージョンハンドル HRGN hRgn = NULL; // 四角形リージョンの数 int nCntRect = 0; // 画面と同じデバイスコンテキストを作成する HDC hDC = CreateCompatibleDC(NULL); if (!hDC) return NULL; // ビットマップを取得する BITMAP bm; GetObject(hBitmap, sizeof(BITMAP), &bm); // 最大要素数で動的配列を作る LPRGNDATA pRgnData = (LPRGNDATA)new BYTE[sizeof(RGNDATAHEADER) + sizeof(RECT) * bm.bmWidth * bm.bmHeight]; LPCOLORREF pScanData = new COLORREF[bm.bmWidth]; if (pRgnData && pScanData){ LPRECT pRect = (LPRECT)pRgnData->Buffer; BITMAPINFOHEADER bi; // ビットマップ情報を作る ZeroMemory(&bi, sizeof(BITMAPINFOHEADER)); bi.biSize = sizeof(BITMAPINFOHEADER); bi.biWidth = bm.bmWidth; bi.biHeight = bm.bmHeight; bi.biPlanes = 1; bi.biBitCount = 32; // 扱うのは 32bit カラー bi.biCompression = BI_RGB; for (int y = 1; y < bm.bmHeight; y++){ // 一行分画像データを DIB で取り出す(bmpなので下から取り出す) GetDIBits(hDC, hBitmap, bm.bmHeight - y, 1, pScanData, (LPBITMAPINFO)&bi, DIB_RGB_COLORS); // 一行分の透明/非透明の変化点を調査する for (int x = 0; x < bm.bmWidth; x++){ if (pScanData[x] != dwTransColor){ // 透明色でなければ pRect->left = x; // その位置から for (; x < bm.bmWidth; x++) // 透明までの if (pScanData[x] == dwTransColor) break; // 長さをカウントする pRect->right = x; // その情報を四角形情報として追加する pRect->top = y - 1; pRect->bottom = y; pRect++; nCntRect++; } } } // 書きためた四角形情報を元にリージョンを作成する pRgnData->rdh.dwSize = sizeof(RGNDATAHEADER); pRgnData->rdh.iType = RDH_RECTANGLES; pRgnData->rdh.nRgnSize = sizeof(RGNDATAHEADER) + sizeof(RECT) * nCntRect; pRgnData->rdh.nCount = nCntRect; pRgnData->rdh.rcBound.top = 0; pRgnData->rdh.rcBound.left = 0; pRgnData->rdh.rcBound.bottom = bm.bmHeight; pRgnData->rdh.rcBound.right = bm.bmWidth; hRgn = ExtCreateRegion(NULL, pRgnData->rdh.nRgnSize, pRgnData); } delete[] pScanData; //** 2005/11/03 バグ修正 delete[] pRgnData; //** 2005/11/03 バグ修正 DeleteDC(hDC); return hRgn; } |