📄 dibitmap.cpp
字号:
delete m_pPal;
m_pPal = 0;
ASSERT( m_pInfo );
// We only need a palette, if there are <= 256 colors.
// otherwise we would bomb the memory.
if( m_pInfo->bmiHeader.biBitCount <= 8 )
m_pPal = new CBmpPalette(this);
return m_pPal ? TRUE : FALSE;
}
void CDIBitmap :: ClearPalette() {
if( m_pPal )
delete m_pPal;
m_pPal = 0;
}
void CDIBitmap :: DrawDIB( CDC* pDC, int x, int y ) {
DrawDIB( pDC, x, y, GetWidth(), GetHeight() );
}
//
// DrawDib uses StretchDIBits to display the bitmap.
void CDIBitmap :: DrawDIB( CDC* pDC, int x, int y, int width, int height ) {
ASSERT( pDC );
HDC hdc = pDC->GetSafeHdc();
CPalette * pOldPal = 0;
if( m_pPal ) {
pOldPal = pDC->SelectPalette( m_pPal, FALSE );
pDC->RealizePalette();
// Make sure to use the stretching mode best for color pictures
pDC->SetStretchBltMode(COLORONCOLOR);
}
if( m_pInfo )
StretchDIBits( hdc,
x,
y,
width,
height,
0,
0,
GetWidth(),
GetHeight(),
GetPixelPtr(),
GetHeaderPtr(),
DIB_RGB_COLORS,
SRCCOPY );
if( m_pPal )
pDC->SelectPalette( pOldPal, FALSE );
}
int CDIBitmap :: DrawDIB( CDC * pDC, CRect & rectDC, CRect & rectDIB ) {
ASSERT( pDC );
HDC hdc = pDC->GetSafeHdc();
CPalette * pOldPal = 0;
if( m_pPal ) {
pOldPal = pDC->SelectPalette( m_pPal, FALSE );
pDC->RealizePalette();
// Make sure to use the stretching mode best for color pictures
pDC->SetStretchBltMode(COLORONCOLOR);
}
int nRet = 0;
if( m_pInfo )
nRet = SetDIBitsToDevice(
hdc, // device
rectDC.left, // DestX
rectDC.top, // DestY
rectDC.Width(), // DestWidth
rectDC.Height(), // DestHeight
rectDIB.left, // SrcX
rectDIB.top, // SrcY
0, // StartScan
GetHeight(), // NumScans
GetPixelPtr(), // color data
GetHeaderPtr(), // header data
DIB_RGB_COLORS // color usage
);
if( m_pPal )
pDC->SelectPalette( pOldPal, FALSE );
return nRet;
}
void CDIBitmap :: FillDIB( CDC * pDC, CRect rc)
{
ASSERT( pDC );
HDC hdc = pDC->GetSafeHdc();
CPalette * pOldPal = 0;
if( m_pPal ) {
pOldPal = pDC->SelectPalette( m_pPal, FALSE );
pDC->RealizePalette();
// Make sure to use the stretching mode best for color pictures
//pDC->SetStretchBltMode(COLORONCOLOR);
}
/*CBrush br;
br.CreateDIBPatternBrush(GetHeaderPtr(), DIB_RGB_COLORS);
pDC->FillRect(&rc, &br);*/
if( m_pInfo )
{
// tile the bitmap
int x=rc.left, y=rc.top;
int h = rc.bottom;
int w = rc.right;
int wBmp = GetWidth();
int hBmp = GetHeight();
int wPart = (rc.Width()+wBmp) % wBmp;
int hPart = (rc.Height()+hBmp) % hBmp;
int wCur, hCur;
BYTE* pPtr = GetPixelPtr();
BITMAPINFO* pHeader = GetHeaderPtr();
while(y < h)
{
hCur = (y + hBmp <= h)? hBmp : hPart;
x = rc.left;
while(x < w)
{
wCur = (x + wBmp <= w)? wBmp : wPart;
StretchDIBits( hdc,
x, y, wCur, hCur,
0, 0, wCur, hCur,
pPtr, pHeader, DIB_RGB_COLORS, SRCCOPY );
x += wCur;
}
y += hCur;
}
}
if( m_pPal )
pDC->SelectPalette( pOldPal, FALSE );
}
BITMAPINFO * CDIBitmap :: GetHeaderPtr() const {
ASSERT( m_pInfo );
ASSERT( m_pPixels );
return m_pInfo;
}
RGBQUAD * CDIBitmap :: GetColorTablePtr() const {
ASSERT( m_pInfo );
ASSERT( m_pPixels );
RGBQUAD* pColorTable = 0;
if( m_pInfo != 0 ) {
int cOffset = sizeof(BITMAPINFOHEADER);
pColorTable = (RGBQUAD*)(((BYTE*)(m_pInfo)) + cOffset);
}
return pColorTable;
}
BYTE * CDIBitmap :: GetPixelPtr() const {
ASSERT( m_pInfo );
ASSERT( m_pPixels );
return m_pPixels;
}
int CDIBitmap :: GetWidth() const {
ASSERT( m_pInfo );
return m_pInfo->bmiHeader.biWidth;
}
int CDIBitmap :: GetHeight() const {
ASSERT( m_pInfo );
return m_pInfo->bmiHeader.biHeight;
}
WORD CDIBitmap :: GetColorCount() const {
ASSERT( m_pInfo );
switch( m_pInfo->bmiHeader.biBitCount ) {
case 1: return 2;
case 4: return 16;
case 8: return 256;
default: return 0;
}
}
int CDIBitmap :: GetPalEntries() const {
ASSERT( m_pInfo );
return GetPalEntries( *(BITMAPINFOHEADER*)m_pInfo );
}
int CDIBitmap :: GetPalEntries( BITMAPINFOHEADER& infoHeader ) const {
int nReturn;
if( infoHeader.biClrUsed == 0 )
nReturn = ( 1 << infoHeader.biBitCount );
else
nReturn = infoHeader.biClrUsed;
return nReturn;
}
DWORD CDIBitmap :: GetBitsPerPixel() const {
ASSERT( m_pInfo );
return m_pInfo->bmiHeader.biBitCount;
}
DWORD CDIBitmap :: LastByte( DWORD dwBitsPerPixel, DWORD dwPixels ) const {
register DWORD dwBits = dwBitsPerPixel * dwPixels;
register DWORD numBytes = dwBits / 8;
register DWORD extraBits = dwBits - numBytes * 8;
return (extraBits % 8) ? numBytes+1 : numBytes;
}
DWORD CDIBitmap :: GetBytesPerLine( DWORD dwBitsPerPixel, DWORD dwWidth ) const {
DWORD dwBits = dwBitsPerPixel * dwWidth;
if( (dwBits % 32) == 0 )
return (dwBits/8); // already DWORD aligned, no padding needed
DWORD dwPadBits = 32 - (dwBits % 32);
return (dwBits/8 + dwPadBits/8 + (((dwPadBits % 8) > 0) ? 1 : 0));
}
BOOL CDIBitmap :: PadBits() {
if( m_bIsPadded )
return TRUE;
// dwAdjust used when bits per pixel spreads over more than 1 byte
DWORD dwAdjust = 1, dwOffset = 0, dwPadOffset=0;
BOOL bIsOdd = FALSE;
dwPadOffset = GetBytesPerLine(GetBitsPerPixel(), GetWidth());
dwOffset = LastByte(GetBitsPerPixel(), GetWidth());
if( dwPadOffset == dwOffset )
return TRUE;
BYTE * pTemp = new BYTE [GetWidth()*dwAdjust];
if( !pTemp ) {
TRACE1("CDIBitmap::PadBits(): could not allocate row of width %d.\n", GetWidth());
return FALSE;
}
// enough space has already been allocated for the bit array to
// include the padding, so we just need to shift rows around.
// This will pad each "row" on a DWORD alignment.
for( DWORD row = GetHeight()-1 ; row>0 ; --row ) {
CopyMemory((void *)pTemp, (const void *)(m_pPixels + (row*dwOffset)), dwOffset );
CopyMemory((void *)(m_pPixels + (row*dwPadOffset)), (const void *)pTemp, dwOffset);
}
delete [] pTemp;
return TRUE;
}
BOOL CDIBitmap::UnPadBits() {
if( ! m_bIsPadded )
return TRUE;
DWORD dwAdjust = 1;
BOOL bIsOdd = FALSE;
DWORD dwPadOffset = GetBytesPerLine(GetBitsPerPixel(), GetWidth());
DWORD dwOffset = LastByte(GetBitsPerPixel(), GetWidth());
BYTE * pTemp = new BYTE [dwOffset];
if( !pTemp ) {
TRACE1("CDIBitmap::UnPadBits() could not allocate row of width %d.\n", GetWidth());
return FALSE;
}
// enough space has already been allocated for the bit array to
// include the padding, so we just need to shift rows around.
for( DWORD row=1 ; row < DWORD(GetHeight()); ++row ) {
CopyMemory((void *)pTemp, (const void *)(m_pPixels + row*(dwPadOffset)), dwOffset);
CopyMemory((void *)(m_pPixels + (row*dwOffset)), (const void *)pTemp, dwOffset);
}
delete [] pTemp;
return TRUE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -