|
서준혁 님이 쓰신 글 :
: 안녕하세요.
: 지난번 임프님의 Q&A 게시판에서 도움을 많이 받았었습니다.
: 이번에도 알고 싶은 것이 있어 글을 남깁니다.
: Canvas에 8bit의 Gray-scale로 그림을 그리고 싶습니다.
: 물론 RGB(R, G, B)를 사용하여 Gray-scale을 구현할 수도 있겠지만,
: 혹시라도 다른 방법이 없을까 해서요.
: RGB를 이용하지 않고 구현할 수 있는 방법이 있으면 좀 가르쳐 주십시오.
: 그럼 고수님들의 친절한 가르침을 기다리겠습니다.
바로 앞의 분 답변은 저로서는 잘 이해가 가지 않네요.
Grayscale이면 R, G, B 값이 같아야 하는데 어떻게 다른 비율로 혼합을 하는 것인지..
암튼, 저도 비트맵에 대해서는 잘 모르지만 다른 사람이 짜놓은 거를 이용해서
잘 쓰고 있기 때문에 그것을 알려드리죠. 바로 팔레트를 변경하는 것입니다.
예제 소스는 256 스텝 Grayscale 팔레트를 가지는 비트맵을 만드는 것이구요..
실제로 그림을 그리는 루틴에서는 (아시겠지만) 비트맵에 Scanline 멤버나
픽셀 등을 이용해 그리신 다음에 Canvas->Draw()를 이용하면 되겠지요.
void __fastcall TForm1::FormCreate(TObject *Sender)
{
m_hGrayPal = Create256GrayPalette();
m_pBitmap1 = new Graphics::TBitmap();
m_pBitmap1->Width = 256;
m_pBitmap1->Height = 256;
m_pBitmap1->PixelFormat = pf8bit;
m_pBitmap1->HandleType = bmDIB;
m_pBitmap1->Palette = m_hGrayPal;
}
HPALETTE __fastcall TForm1::Create256GrayPalette()
{
// create palette
LPLOGPALETTE lpPal; // pointer to a logical palette
HANDLE hLogPal; // handle to a logical palette
HPALETTE hPal = NULL; // handle to a palette
// create palette
// allocate memory block for logical palette
hLogPal = GlobalAlloc(GHND, sizeof(LOGPALETTE) + sizeof(PALETTEENTRY) * 256);
// if not enough memory, clean up and return NULL
if (!hLogPal)
return NULL;
// lock memory block and get pointer to it
lpPal = (LPLOGPALETTE)GlobalLock(hLogPal);
// set version and number of palette entries
lpPal->palVersion = 0x300;
lpPal->palNumEntries = 256;
// store RGB triples (if Win 3.0 DIB) or RGB quads (if OS/2 DIB)
// into palette
for (int i = 0; i < 256; i++){
lpPal->palPalEntry[i].peRed = (char)i;
lpPal->palPalEntry[i].peGreen = (char)i;
lpPal->palPalEntry[i].peBlue = (char)i;
lpPal->palPalEntry[i].peFlags = 0;
}
hPal = CreatePalette(lpPal);
// if error getting handle to palette, clean up and return NULL
if (!hPal){
GlobalUnlock(hLogPal);
GlobalFree(hLogPal);
return NULL;
}
// clean up
GlobalUnlock(hLogPal);
GlobalFree(hLogPal);
return hPal;
}
|