📄 cdib.cpp
字号:
/////////////////////////////////////////////////////////////////////////////
//
// CDIB operations
//
// --- In?: pDC - Pointer to a device context
// ptDest - point at which the topleft corner of the image is drawn
// --- Out :
// --- Returns : TRUE on success
// --- Effect : Draws the image 1:1 on the device context
//
///////////////////////////////////////////////////////////////////////////////
BOOL CDIB::Draw(HDC hDC, POINT& ptDest, BOOL bForceBackground /*=FALSE*/)
{
if (!m_hBitmap)
return FALSE;
SIZE size;
GetSize(size);
POINT ptOrigin = {0,0};
BOOL bResult = FALSE;
// Create a memory DC compatible with the destination DC
HDC hMemDC = GetMemoryDC(hDC, FALSE);
if (!hMemDC)
return FALSE;
#ifndef DIBSECTION_NO_PALETTE
// Select and realize the palette
HPALETTE hOldPalette = NULL;
if (m_hPal && UsesPalette(hDC))
{
hOldPalette = SelectPalette(hDC, m_hPal, bForceBackground );
RealizePalette(hDC);
}
#endif // DIBSECTION_NO_PALETTE
bResult = BitBlt(hDC, ptDest.x, ptDest.y, size.cx, size.cy, hMemDC,
ptOrigin.x, ptOrigin.y, SRCCOPY);
#ifndef DIBSECTION_NO_PALETTE
if (hOldPalette)
SelectPalette(hDC, hOldPalette, FALSE);
#endif // DIBSECTION_NO_PALETTE
ReleaseMemoryDC();
return bResult;
}
///////////////////////////////////////////////////////////////////////////////
//
// --- In?: pDC - Pointer to a device context
// ptDest - point at which the topleft corner of the image is drawn
// size - size to stretch the image
// --- Out :
// --- Returns : TRUE on success
// --- Effect : Stretch draws the image to the desired size on the device context
//
///////////////////////////////////////////////////////////////////////////////
BOOL CDIB::Stretch(HDC hDC, POINT& ptDest, SIZE& size, BOOL bForceBackground /*=FALSE*/)
{
if (!m_hBitmap)
return FALSE;
BOOL bResult = FALSE;
POINT ptOrigin = {0,0};
SIZE imagesize;
GetSize(imagesize);
#ifndef _WIN32_WCE
//pDC->SetStretchBltMode(COLORONCOLOR);
#endif
// Create a memory DC compatible with the destination DC
HDC hMemDC = GetMemoryDC(hDC, FALSE);
if (!hMemDC)
return FALSE;
#ifndef DIBSECTION_NO_PALETTE
// Select and realize the palette
HPALETTE hOldPalette = NULL;
if (m_hPal && UsesPalette(hDC))
{
hOldPalette = SelectPalette(hDC, m_hPal, bForceBackground);
RealizePalette(hDC);
}
#endif // DIBSECTION_NO_PALETTE
bResult = StretchBlt(hDC, ptDest.x, ptDest.y, size.cx, size.cy,
hMemDC, ptOrigin.x, ptOrigin.y, imagesize.cx, imagesize.cy, SRCCOPY);
#ifndef DIBSECTION_NO_PALETTE
if (hOldPalette)
SelectPalette(hDC, hOldPalette, FALSE);
#endif // DIBSECTION_NO_PALETTE
ReleaseMemoryDC();
return bResult;
}
//////////////////////////////////////////////////////////////////////////////
// Setting the bitmap...
//
// --- In?: nIDResource - resource ID
// --- Out :
// --- Returns : Returns TRUE on success, FALSE otherwise
// --- Effect : Initialises the bitmap from a resource. If failure, then object is
// initialised back to an empty bitmap.
//
///////////////////////////////////////////////////////////////////////////////
BOOL CDIB::SetBitmap(UINT nIDResource, HINSTANCE hInst /*= NULL*/ )
{
return SetBitmap(MAKEINTRESOURCE(nIDResource), hInst);
}
///////////////////////////////////////////////////////////////////////////////
//
// --- In?: lpszResourceName - resource name
// --- Out :
// --- Returns : Returns TRUE on success, FALSE otherwise
// --- Effect : Initialises the bitmap from a resource. If failure, then object is
// initialised back to an empty bitmap.
//
///////////////////////////////////////////////////////////////////////////////
BOOL CDIB::SetBitmap(LPCTSTR lpszRes, HINSTANCE hInst /*= NULL*/ )
{
HBITMAP hBmp = (HBITMAP)::LoadImage(hInst, lpszRes, IMAGE_BITMAP, 0,0,0);
if (!hBmp)
{
RETAILMSG(CDIB_DEBUG_MSG, (TEXT("SetBitmap: Unable to LoadImage. \r\n")));
return FALSE;
}
BOOL bResult = SetBitmap(hBmp);
::DeleteObject(hBmp);
return bResult;
}
///////////////////////////////////////////////////////////////////////////////
//
// --- In?: lpBitmapInfo - pointer to a BITMAPINFO structure
// lpBits - pointer to image bits
// --- Out :
// --- Returns : Returns TRUE on success, FALSE otherwise
// --- Effect : Initialises the bitmap using the information in lpBitmapInfo to determine
// the dimensions and colors, and the then sets the bits from the bits in
// lpBits. If failure, then object is initialised back to an empty bitmap.
//
///////////////////////////////////////////////////////////////////////////////
BOOL CDIB::SetBitmap(LPBITMAPINFO lpBitmapInfo, LPVOID lpBits)
{
// DeleteObject();
if (!lpBitmapInfo || !lpBits)
return FALSE;
HDC hDC = NULL;
BITMAPINFOHEADER& bmih = lpBitmapInfo->bmiHeader;
// Compute the number of colors in the color table
m_iColorTableSize = NumColorEntries(bmih.biBitCount, bmih.biCompression);
DWORD dwBitmapInfoSize = sizeof(BITMAPINFO) + m_iColorTableSize*sizeof(RGBQUAD);
// Copy over BITMAPINFO contents
memcpy(&m_DIBinfo, lpBitmapInfo, dwBitmapInfoSize);
// Should now have all the info we need to create the sucker.
//TRACE(_T("Width %d, Height %d, Bits/pixel %d, Image Size %d\n"),
// bmih.biWidth, bmih.biHeight, bmih.biBitCount, bmih.biSizeImage);
// Create a DC which will be used to get DIB, then create DIBsection
hDC = ::GetDC(NULL);
if (!hDC)
{
RETAILMSG(CDIB_DEBUG_MSG, (TEXT("SetBitmap: Unable to get DC. \r\n")));
return FALSE;
}
m_hBitmap = CreateDIBSection(hDC, (LPBITMAPINFO) m_DIBinfo, m_iColorTableSize, &m_ppvBits, NULL, 0);
::ReleaseDC(NULL, hDC);
if (!m_hBitmap)
{
RETAILMSG(CDIB_DEBUG_MSG, (TEXT("SetBitmap: CreateDIBSection failed. \r\n")));
return FALSE;
}
if (m_DIBinfo.bmiHeader.biSizeImage == 0)
{
int nBytesPerLine = BytesPerLine(lpBitmapInfo->bmiHeader.biWidth,
lpBitmapInfo->bmiHeader.biBitCount);
m_DIBinfo.bmiHeader.biSizeImage = nBytesPerLine * lpBitmapInfo->bmiHeader.biHeight;
}
memcpy(m_ppvBits, lpBits, m_DIBinfo.bmiHeader.biSizeImage);
#ifndef DIBSECTION_NO_PALETTE
if (!CreatePalette())
{
RETAILMSG(CDIB_DEBUG_MSG, (TEXT("SetBitmap: Unable to create palette. \r\n")));
return FALSE;
}
#endif // DIBSECTION_NO_PALETTE
return TRUE;
}
//////////////////////////////////////////////////////////////////////////////////
//
// --- In?: hBitmap - handle to image
// pPalette - optional palette to use when setting image
// --- Out :
// --- Returns : Returns TRUE on success, FALSE otherwise
// --- Effect : Initialises the bitmap from the HBITMAP supplied. If failure, then
// object is initialised back to an empty bitmap.
//
///////////////////////////////////////////////////////////////////////////////
BOOL CDIB::SetBitmap(HBITMAP hBitmap, HPALETTE hPal /*= NULL*/)
{
// DeleteObject();
if (!hBitmap)
return FALSE;
// Get dimensions of bitmap
BITMAP bm;
if (!::GetObject(hBitmap, sizeof(bm),(LPVOID)&bm))
return FALSE;
bm.bmHeight = abs(bm.bmHeight);
HDC hDC = GetWindowDC(NULL);
HPALETTE hOldPal = NULL;
m_iColorTableSize = NumColorEntries(bm.bmBitsPixel, BI_RGB);
// Initialize the BITMAPINFOHEADER in m_DIBinfo
BITMAPINFOHEADER& bih = m_DIBinfo.bmiHeader;
bih.biSize = sizeof(BITMAPINFOHEADER);
bih.biWidth = bm.bmWidth;
bih.biHeight = bm.bmHeight;
bih.biPlanes = 1; // Must always be 1 according to docs
bih.biBitCount = bm.bmBitsPixel;
bih.biCompression = BI_RGB;
bih.biSizeImage = BytesPerLine(bm.bmWidth, bm.bmBitsPixel) * bm.bmHeight;
bih.biXPelsPerMeter = 0;
bih.biYPelsPerMeter = 0;
bih.biClrUsed = 0;
bih.biClrImportant = 0;
GetColorTableEntries(hDC, hBitmap);
// If we have a palette supplied, then set the palette (and hance DIB color
// table) using this palette
if (hPal)
SetPalette(hPal);
if (hPal)
{
hOldPal = SelectPalette(hDC, m_hPal, FALSE);
RealizePalette(hDC);
}
// Create it!
m_hBitmap = CreateDIBSection(hDC, (const BITMAPINFO*) m_DIBinfo, m_iColorDataType, &m_ppvBits, NULL, 0);
if (hOldPal)
SelectPalette(hDC, hOldPal, FALSE);
hOldPal = NULL;
if (! m_hBitmap)
{
RETAILMSG(CDIB_DEBUG_MSG, (TEXT("CDIB: SetBitmap: Unable to CreateDIBSection. \r\n")));
return FALSE;
}
// If palette was supplied then create a palette using the entries in the DIB
// color table.
if (! hPal)
CreatePalette();
// Need to copy the supplied bitmap onto the newly created DIBsection
HDC hMemDC = CreateCompatibleDC(hDC);
HDC hCopyDC = CreateCompatibleDC(hDC);
if (! hMemDC || ! hCopyDC)
{
RETAILMSG(CDIB_DEBUG_MSG, (TEXT("CDIB: SetBitmap: Unable to create compatible DCs. \r\n")));
return FALSE;
}
if (m_hPal)
{
SelectPalette(hMemDC, m_hPal, FALSE); RealizePalette(hMemDC);
SelectPalette(hCopyDC, m_hPal, FALSE); RealizePalette(hCopyDC);
}
HBITMAP hOldMemBitmap = (HBITMAP) SelectObject(hMemDC, hBitmap);
HBITMAP hOldCopyBitmap = (HBITMAP) SelectObject(hCopyDC, m_hBitmap);
BitBlt(hCopyDC, 0, 0, bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY);
SelectObject(hMemDC, hOldMemBitmap);
SelectObject(hCopyDC, hOldCopyBitmap);
if (m_hPal)
{
HGDIOBJ hObj = ::GetStockObject(DEFAULT_PALETTE);
SelectObject(hMemDC, hObj);
SelectObject(hCopyDC, hObj);
}
ReleaseDC(NULL, hDC);
return TRUE;
}
//////////////////////////////////////////////////////////////////////////////
// Persistance...
// --- In?: lpszFileName - image filename
// --- Out :
// --- Returns : Returns TRUE on success, FALSE otherwise
// --- Effect : Loads the bitmap from a bitmap file with the name lpszFileName.
// If failure, then object is initialised back to an empty bitmap.
BOOL CDIB::Load(LPCTSTR lpszFileName)
{
FILE *pFile;
if ((pFile = _tfopen(lpszFileName, TEXT("rb"))) == NULL)
{
RETAILMSG(CDIB_ERROR_MSG, (TEXT("Load: Failed to open file.\r\n")));
return FALSE;
}
// Get the current file position.
LONG lFileStart = ftell(pFile);
if (lFileStart == -1L)
{
RETAILMSG(CDIB_ERROR_MSG, (TEXT("Load: Failed to get file current position.\r\n")));
return FALSE;
}
// The first part of the file contains the file header.
// This will tell us if it is a bitmap, how big the header is, and how big
// the file is. The header size in the file header includes the color table.
BITMAPFILEHEADER BmpFileHdr;
int nBytes;
nBytes = fread(&BmpFileHdr, sizeof(BYTE),sizeof(BmpFileHdr), pFile );
if (nBytes != sizeof(BmpFileHdr))
{
RETAILMSG(CDIB_ERROR_MSG, (TEXT("Load: Failed to read file header.\r\n")));
return FALSE;
}
// Check that we have the magic 'BM' at the start.
if (BmpFileHdr.bfType != DS_BITMAP_FILEMARKER)
{
RETAILMSG(CDIB_ERROR_MSG, (TEXT("Load: Not a bitmap file.\r\n")));
return FALSE;
}
// Read the header (assuming it's a DIB).
DIBINFO BmpInfo;
nBytes = fread(&BmpInfo, sizeof(BYTE),sizeof(BITMAPINFOHEADER), pFile );
if (nBytes != sizeof(BITMAPINFOHEADER))
{
RETAILMSG(CDIB_ERROR_MSG, (TEXT("Load: Failed to read BITMAPINFOHEADER.\r\n")));
return FALSE;
}
// Check that we have a real Windows DIB file.
if (BmpInfo.bmiHeader.biSize != sizeof(BITMAPINFOHEADER))
{
RETAILMSG(CDIB_ERROR_MSG, (TEXT("Load: File is not a Windows DIB.\r\n")));
return FALSE;
}
// See how big the color table is in the file (if there is one).
int nColors = NumColorEntries(BmpInfo.bmiHeader.biBitCount, BmpInfo.bmiHeader.biCompression);
if (nColors > 0)
{
// Read the color table from the file.
int nColorTableSize = nColors * sizeof(RGBQUAD);
nBytes = fread(BmpInfo.ColorTable(), sizeof(BYTE), nColorTableSize, pFile );
if (nBytes != nColorTableSize)
{
RETAILMSG(CDIB_ERROR_MSG, (TEXT("Load: Failed to read color table.\r\n")));
return FALSE;
}
}
// So how big the bitmap surface is.
int nBitsSize = BmpFileHdr.bfSize - BmpFileHdr.bfOffBits;
// Double check that the bitmap surface if ok (sometimes the file size is a
// little larger than the bitmap itself, which may cause overflows)
int nSurfaceSize = BytesPerLine(BmpInfo.bmiHeader.biWidth,
BmpInfo.bmiHeader.biBitCount) * BmpInfo.bmiHeader.biHeight;
if (nSurfaceSize < nBitsSize)
{
// In this case we don't need the entire file
nBitsSize = nSurfaceSize;
}
// Allocate the memory for the bits and read the bits from the file.
BYTE* pBits = (BYTE*) malloc(nBitsSize);
if (!pBits)
{
RETAILMSG(CDIB_ERROR_MSG, (TEXT("Load: Out of memory for DIB bits.\r\n")));
return FALSE;
}
// Seek to the bits in the file.
if (fseek( pFile, (lFileStart + BmpFileHdr.bfOffBits), SEEK_SET) != 0)
{
RETAILMSG(CDIB_ERROR_MSG, (TEXT("Load: Failed to seek in file.\r\n")));
return FALSE;
}
// read the bits
nBytes = fread(pBits, sizeof(BYTE), nBitsSize, pFile );
if (nBytes != nBitsSize)
{
RETAILMSG(CDIB_ERROR_MSG, (TEXT("Load: Failed to read bits.\r\n")));
free(pBits);
return FALSE;
}
// Everything went OK.
BmpInfo.bmiHeader.biSizeImage = nBitsSize;
if (!SetBitmap((LPBITMAPINFO) BmpInfo, (LPVOID)pBits))
{
RETAILMSG(CDIB_ERROR_MSG, (TEXT("Load: Failed to set bitmap info.\r\n")));
free(pBits);
return FALSE;
}
free(pBits);
return TRUE;
}
// --- In?: lpszFileName - image filename
// --- Out :
// --- Returns : Returns TRUE on success, FALSE otherwise
// --- Effect : Saves the image to file.
// --- Modificated by Peng Zhuo
BOOL CDIB::Save(LPCTSTR lpszFileName)
{
BITMAPFILEHEADER hdr;
LPBITMAPINFOHEADER lpbi = GetBitmapInfoHeader();
if (!lpbi || !lpszFileName)
return FALSE;
FILE *pFile;
if ((pFile = _tfopen(lpszFileName, TEXT("wb"))) == NULL)
{
RETAILMSG(CDIB_ERROR_MSG, (TEXT("CDIB: Save: Failed to open file.\r\n")));
return FALSE;
}
DWORD dwBitmapInfoSize = sizeof(BITMAPINFO) + (m_iColorTableSize - 1)*sizeof(RGBQUAD);
DWORD dwFileHeaderSize = dwBitmapInfoSize + sizeof(hdr);
// Fill in the fields of the file header
hdr.bfType = DS_BITMAP_FILEMARKER;
hdr.bfSize = dwFileHeaderSize + lpbi->biSizeImage;
hdr.bfReserved1 = 0;
hdr.bfReserved2 = 0;
hdr.bfOffBits = dwFileHeaderSize;
// Write the file header
INT numwritten = fwrite( (void *)&hdr, sizeof(BYTE), sizeof(hdr), pFile );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -