컬러 비트 맵을 회색조로 변환해야합니다. 다음은 접근 방식입니다.C++에서 컬러 비트 맵을 회색조로 변환
HDC hdcWindow = GetDC(hWnd);
HBITMAP hDIBBitmap;
{
// Create a compatible DC which is used in a BitBlt from the window DC
HDC hdcMemDC = CreateCompatibleDC(hdcWindow);
SelectObject(hdcMemDC, bmHatch);
BITMAPINFO bmi;
memset(&bmi, 0, sizeof(BITMAPINFO));
bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmi.bmiHeader.biWidth = bm.bmWidth;
bmi.bmiHeader.biHeight = bm.bmHeight; // top-down
bmi.bmiHeader.biPlanes = bm.bmPlanes;
bmi.bmiHeader.biBitCount = bm.bmBitsPixel;
UINT* pBits;
HBITMAP hDIBBitmap = CreateDIBSection(hdcMemDC, &bmi, DIB_RGB_COLORS, (void**)&pBits, NULL, NULL);
for (int i = 0; i < bm.bmWidth; i++) {
for (int j = 0; j < bm.bmHeight; j++) {
UINT val = pBits[i + j * bm.bmWidth];
if (val != 0)
{
COLORREF clr = val;
UINT newVal = (GetRValue(clr) + GetBValue(clr) + GetGValue(clr))/3;
pBits[i + j * bm.bmWidth] = newVal;
}
}
}
SelectObject(hdcMemDC, hDIBBitmap);
// draw content of memory bitmap in the window
BitBlt(hdcWindow, 0, 0, bm.bmWidth, bm.bmHeight, hdcMemDC, 0, 0, SRCCOPY);
DeleteObject(hDIBBitmap);
DeleteDC(hdcMemDC);
}
ReleaseDC(hWnd, hdcWindow);
위의 코드 샘플에서 입력 비트 맵은 Bitmap 인스턴스 인 bm으로 제공됩니다.
호환되는 DC를 만들었습니다. selectObject 문을 사용하여 비트 맵을로드합니다. 그런 다음 비트 맵 값을 트래버스하기 위해 DIB 섹션을 만들어 비트를 변경하려고합니다. 값을 변경 한 후 hDIBBitmap이 선택되고 마지막으로 BitBlt 함수를 사용하여 그리기됩니다.
다음 줄을 주석 처리하면 원래 비트 맵이 올바르게 렌더링 된 것을 볼 수 있습니다. SelectObject (hdcMemDC, hDIBBitmap);
내가 관찰 한 것은 pBits가 항상 0이므로 변환 된 그레이 스케일 이미지가 렌더링되지 않고 대신에 검은 색 그림을 얻는 것입니다.
이 접근법의 문제점에 대해 조언 해주십시오.
응용 프로그램이이 함수를 호출 할 때 hbmp 매개 변수에 의해 식별 된 값이 ** 장치 컨텍스트로 선택되지 않아야합니다. " SetDIBits도 마찬가지입니다. 또한 비트 맵이 선택된 상태에서 메모리 DC를 삭제합니다. 나는 당신도 memdc가 필요하다고 생각하지 않는다. –
@AdrianMcCarthy 맞습니다. 나는 그 대답을 편집하고 불필요한'SelectObject'를 제거했다. memdc도 제거했다. 'SetDIBits'에서'HDC' 매개 변수를 0으로 설정할 수 있습니다. 그러나'HDDI' 매개 변수가 0이면'GetDIBits'가 실패합니다. 왜 그런지 이해하지 못합니다! –
좋아 보인다! 그리고 네, 저는 GetDIBits가 HDC를 필요로하지 않아도 HDC를 갖는 것에 대해 매우 까다 롭다고 배웠습니다. https://stackoverflow.com/questions/3962237/what-is-the-hdc-for-in-getdibits –