📄 enbitmap.cpp
字号:
else
hRgn = h;
pData->rdh.nCount = 0;
SetRect(&pData->rdh.rcBound, MAXLONG, MAXLONG, 0, 0);
}
}
}
// Go to next row (remember, the bitmap is inverted vertically)
p32 -= bm32.bmWidthBytes;
}
// Create or extend the region with the remaining rectangles
HRGN h = ExtCreateRegion(NULL, sizeof(RGNDATAHEADER) + (sizeof(RECT) * maxRects), pData);
if(hRgn)
{
CombineRgn(hRgn, hRgn, h, RGN_OR);
::DeleteObject(h);
}
else
hRgn = h;
// Clean up
GlobalFree(hData);
SelectObject(hDC, holdBmp);
DeleteDC(hDC);
}
::DeleteObject(SelectObject(hMemDC, holdBmp));
}
DeleteDC(hMemDC);
}
}
return hRgn;
}
BOOL CEnBitmap::Draw(CDC *pDC, LPRECT r)
{
CDC dc;
dc.CreateCompatibleDC( pDC );
CBitmap * bmp = dc.SelectObject( this );
pDC->BitBlt( r->left, r->top, r->right - r->left, r->bottom - r->top, &dc, 0, 0 ,
SRCCOPY );
dc.SelectObject( bmp );
return TRUE;
}
// TransparentBlt - Copies a bitmap transparently onto the destination DC
// hdcDest - Handle to destination device context
// nXDest - x-coordinate of destination rectangle's upper-left corner
// nYDest - y-coordinate of destination rectangle's upper-left corner
// nWidth - Width of destination rectangle
// nHeight - height of destination rectangle
// hBitmap - Handle of the source bitmap
// nXSrc - x-coordinate of source rectangle's upper-left corner
// nYSrc - y-coordinate of source rectangle's upper-left corner
// colorTransparent - The transparent color
// hPal - Logical palette to be used with bitmap. Can be NULL
void CEnBitmap::TransparentBlt(CDC &dc,CRect rc,UINT colorTransparent)
{
CDC pDC;
pDC.CreateCompatibleDC(&dc);
HBITMAP hOldBmp = (HBITMAP) ::SelectObject( pDC.m_hDC, m_hObject );
::TransparentBlt(dc.GetSafeHdc(),rc.left ,rc.top ,rc.Width(),rc.Height(),pDC.GetSafeHdc() ,0,0,GetWidth(),GetHeight(),colorTransparent);
::SelectObject(pDC.m_hDC,hOldBmp);
pDC.DeleteDC();
}
// DrawGreyScale - Draws a bitmap in Grey scale
// pDC - Pointer to target device context
// hDIB - Handle of device-independent bitmap
//
void CEnBitmap::DrawGreyScale( CDC *pDC )
{
CPalette pal;
CPalette *pOldPalette = 0;
HBITMAP hBmp = (HBITMAP)this->GetSafeHandle();
// allocate memory for extended image information
BITMAPINFO &bmInfo= *(LPBITMAPINFO) new BYTE[ sizeof(BITMAPINFO) + 8 ];
memset( &bmInfo, 0, sizeof(BITMAPINFO) + 8 );
bmInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
// get extended information about image (length, compression, length of color table if exist, ...)
DWORD res = GetDIBits(pDC->GetSafeHdc() , hBmp, 0, GetHeight(), 0, &bmInfo, DIB_RGB_COLORS );
// allocate memory for image data (colors)
LPBYTE pBits = new BYTE[ bmInfo.bmiHeader.biSizeImage + 4 ];
res = GetDIBits( pDC->GetSafeHdc(), hBmp, 0, bmInfo.bmiHeader.biHeight, pBits, &bmInfo, DIB_RGB_COLORS );
int nColors = bmInfo.bmiHeader.biClrUsed ? bmInfo.bmiHeader.biClrUsed :
1 << bmInfo.bmiHeader.biBitCount;
int nWidth = bmInfo.bmiHeader.biWidth;
int nHeight = bmInfo.bmiHeader.biHeight;
// Compute the address of the bitmap bits
LPVOID lpDIBBits;
if( bmInfo.bmiHeader.biBitCount > 8 )
lpDIBBits = (LPVOID)((LPDWORD)(pBits +
bmInfo.bmiHeader.biClrUsed) +
((bmInfo.bmiHeader.biCompression == BI_BITFIELDS) ? 3 : 0));
else
lpDIBBits = (LPVOID)(pBits + nColors);
// Create the palette if needed
if( pDC->GetDeviceCaps(RASTERCAPS) & RC_PALETTE && nColors <= 256 )
{
// The device supports a palette and bitmap has color table
// Allocate memory for a palette
UINT nSize = sizeof(LOGPALETTE) + (sizeof(PALETTEENTRY) * nColors);
LOGPALETTE *pLP = (LOGPALETTE *) new BYTE[nSize];
pLP->palVersion = 0x300;
pLP->palNumEntries = nColors;
for( int i=0; i < nColors; i++)
{
int nGrey = Grey( bmInfo.bmiColors[i].rgbRed, bmInfo.bmiColors[i].rgbGreen,
bmInfo.bmiColors[i].rgbBlue );
pLP->palPalEntry[i].peRed = nGrey;
pLP->palPalEntry[i].peGreen = nGrey;
pLP->palPalEntry[i].peBlue = nGrey;
pLP->palPalEntry[i].peFlags = 0;
}
pal.CreatePalette( pLP );
delete[] pLP;
// Select the palette
pOldPalette = pDC->SelectPalette(&pal, FALSE);
pDC->RealizePalette();
}
else
{
// Modify the bitmaps pixels directly
// Note : This ends up changing the DIB. If that is not acceptable then
// copy the DIB and then change the copy rather than the original
if ( bmInfo.bmiHeader.biBitCount == 24 || bmInfo.bmiHeader.biBitCount == 32)
{
BYTE *dst=(BYTE*)lpDIBBits;
int Size=nWidth*nHeight;
while ( Size-- )
{
int nGrey = Grey( dst[2], dst[1], dst[0] );
dst[0]=(BYTE)nGrey;
dst[1]=(BYTE)nGrey;
dst[2]=(BYTE)nGrey;
dst+=4;
}
}
else if ( bmInfo.bmiHeader.biBitCount == 16 )
{
WORD *dst=(WORD*)lpDIBBits;
int Size=nWidth*nHeight;
while ( Size-- )
{
BYTE b = (BYTE)((*dst)&(0x1F));
BYTE g = (BYTE)(((*dst)>>5)&(0x1F));
BYTE r = (BYTE)(((*dst)>>10)&(0x1F));
int nGrey = Grey( r, g, b );
*dst++ = ((WORD)(((BYTE)(nGrey)|((WORD)((BYTE)(nGrey))<<5))|(((DWORD)(BYTE)(nGrey))<<10)));
}
}
}
// Draw the image
::SetDIBitsToDevice(pDC->m_hDC, // hDC
0, // XDest
0, // YDest
nWidth, // nDestWidth
nHeight, // nDestHeight
0, // XSrc
0, // YSrc
0, // nStartScan
nHeight, // nNumScans
lpDIBBits, // lpBits
&bmInfo, // lpBitsInfo
DIB_RGB_COLORS); // wUsage
if ( pOldPalette )
pDC->SelectPalette(pOldPalette, FALSE);
}
//
// DitherBlt : Draw a bitmap dithered (3D grayed effect like disabled buttons in toolbars) into a destination DC
// Author : Jean-Edouard Lachand-Robert (iamwired@geocities.com), June 1997.
//
// hdcDest : destination DC
// nXDest : x coordinate of the upper left corner of the destination rectangle into the DC
// nYDest : y coordinate of the upper left corner of the destination rectangle into the DC
// nWidth : width of the destination rectangle into the DC
// nHeight : height of the destination rectangle into the DC
// hbm : the bitmap to draw (as a part or as a whole)
// nXSrc : x coordinates of the upper left corner of the source rectangle into the bitmap
// nYSrc : y coordinates of the upper left corner of the source rectangle into the bitmap
//
void CEnBitmap::DitherBlt (HDC hdcDest, int nXDest, int nYDest, int nWidth,
int nHeight, HBITMAP hbm, int nXSrc, int nYSrc)
{
ASSERT(hdcDest && hbm);
ASSERT(nWidth > 0 && nHeight > 0);
// Create a generic DC for all BitBlts
HDC hDC = CreateCompatibleDC(hdcDest);
ASSERT(hDC);
if (hDC)
{
// Create a DC for the monochrome DIB section
HDC bwDC = CreateCompatibleDC(hDC);
ASSERT(bwDC);
if (bwDC)
{
// Create the monochrome DIB section with a black and white palette
struct {
BITMAPINFOHEADER bmiHeader;
RGBQUAD bmiColors[2];
} RGBBWBITMAPINFO = {
{ // a BITMAPINFOHEADER
sizeof(BITMAPINFOHEADER), // biSize
nWidth, // biWidth;
nHeight, // biHeight;
1, // biPlanes;
1, // biBitCount
BI_RGB, // biCompression;
0, // biSizeImage;
0, // biXPelsPerMeter;
0, // biYPelsPerMeter;
0, // biClrUsed;
0 // biClrImportant;
},
{
{ 0x00, 0x00, 0x00, 0x00 }, { 0xFF, 0xFF, 0xFF, 0x00 }
}
};
VOID *pbitsBW;
HBITMAP hbmBW = CreateDIBSection(bwDC,
(LPBITMAPINFO)&RGBBWBITMAPINFO, DIB_RGB_COLORS, &pbitsBW, NULL, 0);
ASSERT(hbmBW);
if (hbmBW)
{
// Attach the monochrome DIB section and the bitmap to the DCs
SelectObject(bwDC, hbmBW);
SelectObject(hDC, hbm);
// BitBlt the bitmap into the monochrome DIB section
BitBlt(bwDC, 0, 0, nWidth, nHeight, hDC, nXSrc, nYSrc, SRCCOPY);
// Paint the destination rectangle in gray
FillRect(hdcDest, CRect(nXDest, nYDest, nXDest + nWidth, nYDest +
nHeight), GetSysColorBrush(COLOR_3DFACE));
// BitBlt the black bits in the monochrome bitmap into COLOR_3DHILIGHT bits in the destination DC
// The magic ROP comes from the Charles Petzold's book
HBRUSH hb = CreateSolidBrush(GetSysColor(COLOR_3DHILIGHT));
HBRUSH oldBrush = (HBRUSH)SelectObject(hdcDest, hb);
BitBlt(hdcDest, nXDest + 1, nYDest + 1, nWidth, nHeight, bwDC, 0, 0, 0xB8074A);
// BitBlt the black bits in the monochrome bitmap into COLOR_3DSHADOW bits in the destination DC
hb = CreateSolidBrush(GetSysColor(COLOR_3DSHADOW));
::DeleteObject(SelectObject(hdcDest, hb));
BitBlt(hdcDest, nXDest, nYDest, nWidth, nHeight, bwDC, 0, 0, 0xB8074A);
::DeleteObject(SelectObject(hdcDest, oldBrush));
}
VERIFY(DeleteDC(bwDC));
}
VERIFY(DeleteDC(hDC));
}
}
// CreateReservedPalette - Create a palette using the PC_RESERVED flag
// Limit the colors to 236 colors
// Returns - Handle to a palette object
// hDIB - Handle to a device-independent bitmap
//
HPALETTE CEnBitmap::CreateReservedPalette(CDC *pDC)
{
HPALETTE hPal = NULL; // handle to a palette
HBITMAP hBmp = (HBITMAP)this->GetSafeHandle();
// get image properties
//BITMAP bmp = { 0 };
//::GetObject( hBmp, sizeof(BITMAP), &bmp );
// allocate memory for extended image information
BITMAPINFO &bmInfo= *(LPBITMAPINFO) new BYTE[ sizeof(BITMAPINFO) + 8 ];
memset( &bmInfo, 0, sizeof(BITMAPINFO) + 8 );
bmInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
// get extended information about image (length, compression, length of color table if exist, ...)
DWORD res = GetDIBits(pDC->GetSafeHdc() , hBmp, 0, GetHeight(), 0, &bmInfo, DIB_RGB_COLORS );
// allocate memory for image data (colors)
LPBYTE pBits = new BYTE[ bmInfo.bmiHeader.biSizeImage + 4 ];
res = GetDIBits( pDC->GetSafeHdc(), hBmp, 0, bmInfo.bmiHeader.biHeight, pBits, &bmInfo, DIB_RGB_COLORS );
int nWidth = bmInfo.bmiHeader.biWidth;
int nHeight = bmInfo.bmiHeader.biHeight;
int nColors = bmInfo.bmiHeader.biClrUsed ? bmInfo.bmiHeader.biClrUsed :
1 << bmInfo.bmiHeader.biBitCount;
if( nColors > 256 )
return NULL; // No Palette
//allocate memory block for logical palette
UINT nSize = sizeof(LOGPALETTE) + (sizeof(PALETTEENTRY) * nColors);
LOGPALETTE *pLP = (LOGPALETTE *) new BYTE[nSize];
// Initialize the palette version
pLP->palVersion = 0x300;
// If it is a 256 color DIB, then let's find the most used 236 colors
// and make a palette out of those colors
if (nColors > 236)
{
typedef struct _tagBESTCOLORS
{
DWORD dwColorCnt; //Count of how many times a color is used
BOOL bDontUse; //Should we use this color?
} BESTCOLORS;
BESTCOLORS bc[256];
BYTE dwLeastUsed[20]; // Least used color indices
LPSTR lpBits; // pointer to D.I. bits of a DIB
int nWidth, nHeight, nBytesPerLine, cx, cy;
::ZeroMemory( bc, 256*sizeof(BESTCOLORS));
lpBits = (LPSTR)(pBits + nColors);
nWidth = bmInfo.bmiHeader.biWidth;
nHeight = bmInfo.bmiHeader.biHeight;
nBytesPerLine = ((((bmInfo.bmiHeader.biWidth *
bmInfo.bmiHeader.biBitCount) + 31) & ~31) / 8);
// Traverse through all of the bits in the bitmap and place the
// color count of each color in the BESTCOLORS array
for (cy = 0; cy < nHeight; cy++)
for (cx = 0; cx < nWidth; cx++)
bc[*(LPBYTE)(lpBits+cy*nBytesPerLine+cx)].dwColorCnt++;
// Let's arbitrarily place the first few colors in the "Least Used" list.
int nReject = nColors - 236;
for (cx=0; cx < nReject; cx++)
{
bc[cx].bDontUse = TRUE;
dwLeastUsed[cx] = cx;
}
// Now, let's traverse through all of the colors and
// sort out the least used
for (cx=0; cx < nColors; cx++)
{
cy = 0;
while ((!(bc[cx].bDontUse)) && cy < nReject)
{
if (bc[cx].dwColorCnt < bc[dwLeastUsed[cy]].dwColorCnt)
{
bc[dwLeastUsed[cy]].bDontUse = FALSE;
dwLeastUsed[cy] = cx;
bc[cx].bDontUse = TRUE;
}
cy++;
}
}
// We want only 236 colors, so that the 20 system colors
// are left untouched
pLP->palNumEntries = 236;
cx = 0;
for(int i = 0; i < nColors; i++)
{
// Should we use this color?
if (!((bc[i].bDontUse)))
{
pLP->palPalEntry[cx].peRed = bmInfo.bmiColors[i].rgbRed;
pLP->palPalEntry[cx].peGreen =
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -