📄 enbitmap.cpp
字号:
bmInfo.bmiColors[i].rgbGreen;
pLP->palPalEntry[cx].peBlue = bmInfo.bmiColors[i].rgbBlue;
pLP->palPalEntry[cx].peFlags = PC_RESERVED;
cx++;
}
}
}
else if (nColors)
{
// We have enough room for all the colors
pLP->palNumEntries = nColors;
// Copy the colors
for(int i = 0; i < nColors; i++)
{
pLP->palPalEntry[i].peRed = bmInfo.bmiColors[i].rgbRed;
pLP->palPalEntry[i].peGreen = bmInfo.bmiColors[i].rgbGreen;
pLP->palPalEntry[i].peBlue = bmInfo.bmiColors[i].rgbBlue;
pLP->palPalEntry[i].peFlags = PC_RESERVED;
}
}
hPal = CreatePalette( pLP );
delete[] pLP;
// return handle to DIB's palette
return hPal;
}
// FadeColorToGrayScale - Draws a bitmap in color slowly turns it to grayscale
// pDC - Pointer to target device context
// hDIB - Handle of device-independent bitmap
// xDest - x-coordinate of upper-left corner of dest. rect.
// yDest - y-coordinate of upper-left corner of dest. rect.
// nLoops - How many loops to fade the image into color
// nDelay - Delay in milli-seconds between each loop
//
void CEnBitmap::FadeColorToGrayScale( CDC *pDC,int xDest, int yDest, int nLoops,
int nDelay )
{
CPalette pal;
CPalette *pOldPalette;
PALETTEENTRY peAnimate[256];
PALETTEENTRY peGray[256];
PALETTEENTRY peOriginal[256];
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 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);
int nReservedColors = nColors > 236 ? 236 : nColors;
// Create the palette if needed
if( pDC->GetDeviceCaps(RASTERCAPS) & RC_PALETTE && nColors <= 256 )
{
// The device supports a palette and bitmap has color table
HPALETTE hPal = CreateReservedPalette(pDC);
pal.Attach( hPal );
// Now save the original colors and get the grayscale colors
pal.GetPaletteEntries(0, nReservedColors, (LPPALETTEENTRY)&peOriginal);
for( int i=0; i < nReservedColors; i++)
{
int nGray = Grey( peOriginal[i].peRed, peOriginal[i].peGreen , peOriginal[i].peBlue );
peGray[i].peRed = nGray;
peGray[i].peGreen = nGray;
peGray[i].peBlue = nGray;
}
// Select the palette
pOldPalette = pDC->SelectPalette(&pal, FALSE);
pDC->RealizePalette();
::SetDIBitsToDevice(pDC->m_hDC, xDest, yDest, nWidth, nHeight, 0, 0, 0,
nHeight, lpDIBBits, (LPBITMAPINFO)&bmInfo, DIB_RGB_COLORS);
// Now animate palette to set the image to grayscale
for( i=1; i <= nLoops; i++ )
{
for (int j = 0; j< nColors; j++)
{
peAnimate[j].peRed = peOriginal[j].peRed -
((peOriginal[j].peRed -peGray[j].peRed)*i)/nLoops;
peAnimate[j].peGreen = peOriginal[j].peGreen -
((peOriginal[j].peGreen-peGray[j].peGreen)*i)
/nLoops;
peAnimate[j].peBlue = peOriginal[j].peBlue -
((peOriginal[j].peBlue -peGray[j].peBlue)*i)/nLoops;
peAnimate[j].peFlags = peOriginal[j].peFlags;
}
pal.AnimatePalette(0, nColors, (LPPALETTEENTRY)&peAnimate);
// Delay...
Sleep(nDelay);
}
// Select the old palette back
pDC->SelectPalette(pOldPalette, FALSE);
}
else if( (pDC->GetDeviceCaps(RASTERCAPS) & RC_PALETTE) == 0 && nColors <= 256 )
{
// Now change the image to grayscale
for(int i=1; i <= nLoops; i++ )
{
BYTE *dst=(BYTE*)lpDIBBits;
int Size=nWidth*nHeight;
while ( Size-- )
{
int nGrey = Grey( dst[2], dst[1], dst[0] );
dst[2]=(BYTE)dst[2] -((dst[2] -nGrey)*i)/nLoops;
dst[1]=(BYTE)dst[1] -((dst[1] -nGrey)*i)/nLoops;
dst[0]=(BYTE)dst[0] -((dst[0] -nGrey)*i)/nLoops;
dst+=4;
}
// Draw the image again
::SetDIBitsToDevice(pDC->m_hDC, xDest, yDest, nWidth, nHeight, 0,
0, 0, nHeight, lpDIBBits, (LPBITMAPINFO)&bmInfo,
DIB_RGB_COLORS);
// Delay...
Sleep(nDelay);
}
}
else
{
::SetDIBitsToDevice(pDC->m_hDC, xDest, yDest, nWidth, nHeight, 0, 0, 0,
nHeight, lpDIBBits, (LPBITMAPINFO)&bmInfo, DIB_RGB_COLORS);
}
}
void CEnBitmap::AlphaDisplay(CDC *pDC, BYTE bAlpha)
{
CDC dc;
dc.CreateCompatibleDC( pDC );
CBitmap * bmp = dc.SelectObject( this );
BLENDFUNCTION rBlendProps;
rBlendProps.BlendOp = AC_SRC_OVER;
rBlendProps.BlendFlags = 0;
rBlendProps.AlphaFormat = 0;
rBlendProps.SourceConstantAlpha = bAlpha;
BITMAP bmInfo;
::GetObject(m_hObject, sizeof(BITMAP), &bmInfo );
INT nWidth, nHeigh;
nWidth = bmInfo.bmWidth;
nHeigh = bmInfo.bmHeight;
AlphaBlend(pDC->m_hDC, 0, 0, nWidth, nHeigh, dc.m_hDC , 0, 0,
nWidth, nHeigh, rBlendProps );
dc.SelectObject( bmp );
}
/* ExtCreateRegion replacement */
HRGN CEnBitmap::CreateRegionExt(DWORD nCount, CONST RGNDATA *pRgnData )
{
HRGN hRgn=CreateRectRgn(0, 0, 0, 0);
const DWORD RDHDR = sizeof(RGNDATAHEADER);
ASSERT( hRgn!=NULL );
LPRECT pRects = (LPRECT)((LPBYTE)pRgnData + RDHDR);
for(int i=0;i<(int)nCount;i++)
{
HRGN hr=CreateRectRgn(pRects[i].left, pRects[i].top, pRects[i].right, pRects[i].bottom);
VERIFY(CombineRgn(hRgn, hRgn, hr, RGN_OR)!=ERROR);
if (hr)
::DeleteObject(hr);
}
ASSERT( hRgn!=NULL );
return hRgn;
}
///////////////////////////////////////////////////////////////////
// InflateRegion - Inflates a region by the x and y values
// specified in nXInflate and nYInflate
// Creates a new region that represents the inflated region
// (retains the contents of the old region)
// Returns NULL if unsuccessfull
HRGN CEnBitmap::InflateRegion(HRGN hRgn, int nXInflate, int nYInflate)
{
// Local Variables
LPRGNDATA lpData; // The RGNDATA structure
LPRECT lpRect; // Pointer to the array of RECT structures
DWORD BufSize; // The amount of memory required
DWORD i; // General index variable
HRGN hRgnNew; // The newly created region
// Get the number of rectangles in the region
BufSize = GetRegionData(hRgn, 0, NULL);
if(BufSize == 0)
return NULL;
// Allocate memory for the RGNDATA structure
lpData = (LPRGNDATA)malloc(BufSize);
// Set the location of the RECT structures
lpRect = (LPRECT)(lpData->Buffer);
// Get the region data
if(!GetRegionData(hRgn, BufSize, lpData))
{
free(lpData);
return NULL;
}
// Expand (or contract) all the rectangles in the data
for(i=0; i<lpData->rdh.nCount; i++)
InflateRect(&lpRect[i], nXInflate, nYInflate);
// Create the new region
hRgnNew = CreateRegionExt(lpData->rdh.nCount, lpData);
free((void*)lpData);
return hRgnNew;
}
BOOL CEnBitmap::StretchDraw(CDC *pDC, LPRECT r, LPRECT sr )
{
if ( !r )
return FALSE;
CDC dc;
dc.CreateCompatibleDC( pDC );
CBitmap * bmp = dc.SelectObject( this );
//pDC->SetStretchBltMode(COLORONCOLOR);
if ( !sr )
pDC->StretchBlt( r->left, r->top, r->right, r->bottom, &dc, 0, 0, GetWidth(), GetHeight() ,
SRCCOPY );
else
pDC->StretchBlt( r->left, r->top, r->right - r->left, r->bottom - r->top, &dc, sr->left, sr->top,
sr->right - sr->left, sr->bottom - sr->top,
SRCCOPY );
dc.SelectObject( bmp );
return TRUE;
}
BOOL CEnBitmap::DrawImage(CEnBitmap &bmp,int nX,int nY,int nCol,int nRow)
{
nX-=1;
nY-=1;
//单个图片的长和宽
int w = GetWidth()/nCol;
int h = GetHeight()/nRow;
CBitmap *OldBmp;
CDC memDC;
CClientDC dc(0);
memDC.CreateCompatibleDC(&dc);
bmp.CreateCompatibleBitmap(&dc, w, h);
OldBmp = memDC.SelectObject( &bmp );
StretchDraw(&memDC, CRect( 0, 0, w, h ),CRect(GetWidth()*nX/nCol, GetHeight()*nY/nRow, GetWidth()*nX/nCol+w ,GetHeight()*nY/nRow+h ));
memDC.SelectObject(OldBmp);
return TRUE;
}
CRect CEnBitmap::GetRect()
{
return CRect(0,0,GetWidth(),GetHeight());
}
HBITMAP CEnBitmap::SetBitmap(HBITMAP hBitmap)
{
CEnBitmap *pBmp=(CEnBitmap *)CEnBitmap::FromHandle(hBitmap);
HBITMAP hBmp=(HBITMAP)this->Detach();
this->DeleteObject();
pBmp->DrawImage(*this,1,1,1,1);
return hBmp;
}
BOOL CEnBitmap::ExtendDraw(CDC *pDC,CRect rc, int nX, int nY)
{
CEnBitmap bmp;
if (ExtendDrawImage(bmp,rc,nX,nY))
{
bmp.Draw(pDC,&rc);
return TRUE;
}
return FALSE;
}
BOOL CEnBitmap::ExtendDrawImage(CEnBitmap &bmp,CRect rc, int nX, int nY)
{
CBitmap *OldBmp;
CDC memDC;
CClientDC cdc(0);
memDC.CreateCompatibleDC(&cdc);
bmp.CreateCompatibleBitmap(&cdc, rc.Width() , rc.Height() );
OldBmp = memDC.SelectObject( &bmp );
if (nX==0 && nY==0)
{
StretchDraw(&memDC,&rc,GetRect());
return TRUE;
}
CDC dc;
dc.CreateCompatibleDC(&memDC);
CBitmap * Bmp = dc.SelectObject( this );
//dc.SetStretchBltMode(COLORONCOLOR);
if (nX!=0 && nY==0)
{
//坐上角
memDC.BitBlt( 0, 0, nX, rc.Height(), &dc, 0, 0,
SRCCOPY );
memDC.StretchBlt(nX, 0, rc.Width()-GetWidth(), rc.Height() , &dc,nX, 0, 1, GetHeight(),
SRCCOPY );
//右上角
memDC.BitBlt(rc.right-(GetWidth()-nX), 0, GetWidth()-nX, rc.Height() , &dc,nX, 0,
SRCCOPY );
}
else if (nX==0 && nY!=0)
{
//上角
memDC.BitBlt( 0, 0, rc.Width(), nY, &dc, 0, 0,
SRCCOPY );
memDC.StretchBlt(0, nY, GetWidth(), rc.Height()-GetHeight(), &dc,0, nY, GetWidth(), 1,
SRCCOPY );
//右上角
memDC.BitBlt(0, rc.bottom-(GetHeight()-nY), GetWidth(), GetHeight()-nY , &dc,0, nY,
SRCCOPY );
}
else
{
//坐上角
memDC.StretchBlt( 0, 0, nX, nY, &dc, 0, 0, nX, nY ,
SRCCOPY );
//上中
memDC.StretchBlt(nX, 0, rc.Width()-GetWidth(),nY, &dc, nX, 0, 1, nY ,
SRCCOPY );
//右上角
memDC.StretchBlt(rc.Width()-(GetWidth()-nX), 0, GetWidth()-nX, nY , &dc,nX, 0, GetWidth()-nX, nY,
SRCCOPY );
//左中
memDC.StretchBlt(0, nY, nX,rc.Height()-GetHeight(), &dc, 0, nY, nX, 1 ,
SRCCOPY );
//正中
memDC.StretchBlt(nX, nY, rc.Width()-GetWidth(),rc.Height()-GetHeight(), &dc, nX, nY, 1, 1 ,
SRCCOPY );
//右中
memDC.StretchBlt(rc.Width()-(GetWidth()-nX), nY, GetWidth()-nX,rc.Height()-GetHeight(), &dc, nX, nY, GetWidth()-nX, 1 ,
SRCCOPY );
//左下角
memDC.StretchBlt( 0, rc.Height()-(GetHeight()-nY), nX, GetHeight()-nY, &dc, 0, nY, nX,GetHeight()-nY ,
SRCCOPY );
//下中
memDC.StretchBlt(nX, rc.Height()-(GetHeight()-nY), rc.Width()-GetWidth(),GetHeight()-nY, &dc, nX, nY, 1, GetHeight()-nY ,
SRCCOPY );
//右下角
memDC.StretchBlt( rc.Width()-(GetWidth()-nX), rc.Height()-(GetHeight()-nY), GetWidth()-nX, GetHeight()-nY, &dc, nX, nY, GetWidth()-nX,GetHeight()-nY ,
SRCCOPY );
}
dc.SelectObject( Bmp );
memDC.SelectObject(OldBmp);
return TRUE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -