void CDib::CreatePaletteFromImage( CPalette& palette)const { if( palette.m_hObject ) palette.DeleteObject(); ASSERT( IsIndexed() == GetBPP() <= 8); if( GetBPP() <= 8) { GetPalette(palette); //CPalette* pal = CPalette::FromHandle(m_hPalette); //PALETTEENTRY colors[256] = {0}; //pal->GetPaletteEntries(0, 256, colors); //palette.SetPaletteEntries( 0, 256, colors ); } else { LPLOGPALETTE pLogPal = (LPLOGPALETTE) new char[2 * sizeof(WORD) + 256 * sizeof(PALETTEENTRY)]; pLogPal->palVersion = 0x300; pLogPal->palNumEntries = 256; palette.CreatePalette(pLogPal); delete pLogPal; pLogPal = NULL; CArray<COLORREF, COLORREF> colorArray; int height= GetHeight(); int width = GetWidth(); for(int i=0; i<width; i++) { for(int j=0; j<height; j++) { COLORREF color = GetPixel(i, j); if( UtilWin::FindInArray( colorArray, color) == -1) colorArray.Add(color); if( colorArray.GetSize() == 256) break; } if( colorArray.GetSize() == 256) break; } PALETTEENTRY pe[256]={0}; for (int i = 0; i < colorArray.GetSize(); i++) { COLORREF color = colorArray[i]; pe[i].peRed = GetRValue(color); pe[i].peGreen = GetGValue(color); pe[i].peBlue = GetBValue(color); } palette.SetPaletteEntries(0, 256, pe); } }
BOOL CDib::GetPalette(CPalette& palette)const { if( (HPALETTE)palette) palette.DeleteObject(); /*HDC hDC = GetDC(); CPalette* pPalette = CPalette::FromHandle( (HPALETTE)GetCurrentObject(hDC, OBJ_PAL)); int iColors = 0; if (!pPalette->GetObject(sizeof(int), &iColors)) { TRACE("Failed to get num palette colors"); return FALSE; } ReleaseDC(); */ int iColors = GetMaxColorTableEntries(); if(iColors==0) return FALSE; RGBQUAD quad[256] = {0}; //LPRGBQUAD pctThis = (LPRGBQUAD) &quad; GetColorTable(0, iColors, &quad[0]); LPLOGPALETTE pLogPal = (LPLOGPALETTE) new char[2 * sizeof(WORD) + iColors * sizeof(PALETTEENTRY)]; pLogPal->palVersion = 0x300; pLogPal->palNumEntries = iColors; for (int i = 0; i < iColors; i++) { pLogPal->palPalEntry[i].peRed = quad[i].rgbRed; pLogPal->palPalEntry[i].peGreen = quad[i].rgbGreen; pLogPal->palPalEntry[i].peBlue = quad[i].rgbBlue; } palette.CreatePalette(pLogPal); delete pLogPal; return true; }
HANDLE CImageWindow::DDBToDIB(CDC* pDC, CBitmap &Bitmap, CPalette *pPal) { if( !pDC ) return NULL; BITMAP Bmp; BITMAPINFO BmpInfo; CPalette Palette; CPalette* pOldPalette = NULL; //기본 팔레트 생성 Palette.CreateStockObject(DEFAULT_PALETTE); //비트맵 정보를 얻는다. Bitmap.GetBitmap(&Bmp); ////////////////////////////////////////////////////////////////////////// // 1. 비트맵 해더를 초기화 한다. BmpInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); BmpInfo.bmiHeader.biWidth = Bmp.bmWidth; BmpInfo.bmiHeader.biHeight = Bmp.bmHeight; BmpInfo.bmiHeader.biPlanes = 1; BmpInfo.bmiHeader.biBitCount = Bmp.bmPlanes * Bmp.bmBitsPixel; BmpInfo.bmiHeader.biCompression = BI_RGB; BmpInfo.bmiHeader.biSizeImage = 0; BmpInfo.bmiHeader.biXPelsPerMeter = 0; BmpInfo.bmiHeader.biYPelsPerMeter = 0; BmpInfo.bmiHeader.biClrUsed = 0; BmpInfo.bmiHeader.biClrImportant = 0; //비트맵 헤더와 컬러 테이블의 크기를 계산한다. int nColors = (1 << BmpInfo.bmiHeader.biBitCount); if (nColors > 256){ nColors = 0; } DWORD dwImageLength = BmpInfo.bmiHeader.biSize + nColors * sizeof(RGBQUAD); //저장할 윈도우의 팔레트를 기본 팔레트로 설정한다. pOldPalette = pDC->SelectPalette(&Palette, FALSE); pDC->RealizePalette(); //DIB가 저장될 메모리(비트맵 정보 헤더와 컬러 테이블)을 할당한다. HANDLE hDIB = ::GlobalAlloc(GPTR, dwImageLength); if (hDIB == NULL) { pDC->SelectPalette(pOldPalette, FALSE); return NULL; } ////////////////////////////////////////////////////////////////////////// //2. 비트맵 이미지의 크기를 계산한다. ::GetDIBits(pDC->GetSafeHdc(), (HBITMAP)Bitmap.GetSafeHandle(), 0L, BmpInfo.bmiHeader.biHeight, NULL, //이 값이 NULL이면 이미지 크기를 계산. (LPBITMAPINFO)&BmpInfo.bmiHeader, DIB_RGB_COLORS); if (BmpInfo.bmiHeader.biSizeImage == 0) { pDC->SelectPalette(pOldPalette, FALSE); GlobalFree(hDIB); return NULL; } ////////////////////////////////////////////////////////////////////////// //3. DIB 이미지를 구함. dwImageLength += BmpInfo.bmiHeader.biSizeImage; HANDLE hRealloc = ::GlobalReAlloc(hDIB, dwImageLength, GMEM_MOVEABLE); if (hRealloc != NULL) { hDIB = hRealloc; } else { pDC->SelectPalette(pOldPalette, FALSE); GlobalFree(hDIB); return NULL; } //DDB에서 DIB로 변환된 이미지를 구함. if (!::GetDIBits(pDC->GetSafeHdc(), (HBITMAP)Bitmap.GetSafeHandle(), 0L, // Start scan line (DWORD)BmpInfo.bmiHeader.biHeight, //# of scan lines (LPBYTE)hDIB + (BmpInfo.bmiHeader.biSize + nColors * sizeof(RGBQUAD)), (LPBITMAPINFO)&BmpInfo.bmiHeader, //address of bitmapinfo (DWORD)DIB_RGB_COLORS)) { pDC->SelectPalette(pOldPalette, FALSE); GlobalFree(hDIB); return NULL; } //DIB 헤더 작성 memcpy(hDIB, &BmpInfo.bmiHeader, sizeof(BITMAPINFOHEADER)); pDC->SelectPalette(pOldPalette, FALSE); Palette.DeleteObject(); return hDIB; }