📄 dibapi.cpp
字号:
// alloc memory block to store our bitmap
hDIB = GlobalAlloc(GHND, dwLen);
// if we couldn't get memory block
if (!hDIB)
{
// clean up and return NULL
SelectPalette(hDC, hPal, TRUE);
RealizePalette(hDC);
ReleaseDC(NULL, hDC);
return NULL;
}
// lock memory and get pointer to it
lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB);
/// use our bitmap info. to fill BITMAPINFOHEADER
*lpbi = bi;
// call GetDIBits with a NULL lpBits param, so it will calculate the
// biSizeImage field for us
GetDIBits(hDC, hBitmap, 0, (UINT)bi.biHeight, NULL, (LPBITMAPINFO)lpbi,
DIB_RGB_COLORS);
// get the info. returned by GetDIBits and unlock memory block
bi = *lpbi;
GlobalUnlock(hDIB);
// if the driver did not fill in the biSizeImage field, make one up
if (bi.biSizeImage == 0)
bi.biSizeImage = WIDTHBYTES((DWORD)bm.bmWidth * biBits) * bm.bmHeight;
// realloc the buffer big enough to hold all the bits
dwLen = bi.biSize + PaletteSize((LPBYTE)&bi) + bi.biSizeImage;
if (h = GlobalReAlloc(hDIB, dwLen, 0))
hDIB = h;
else
{
// clean up and return NULL
GlobalFree(hDIB);
hDIB = NULL;
SelectPalette(hDC, hPal, TRUE);
RealizePalette(hDC);
ReleaseDC(NULL, hDC);
return NULL;
}
// lock memory block and get pointer to it */
lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB);
// call GetDIBits with a NON-NULL lpBits param, and actualy get the
// bits this time
if (GetDIBits(hDC, hBitmap, 0, (UINT)bi.biHeight, (LPBYTE)lpbi +
(WORD)lpbi->biSize + PaletteSize((LPBYTE)lpbi), (LPBITMAPINFO)lpbi,
DIB_RGB_COLORS) == 0)
{
// clean up and return NULL
GlobalUnlock(hDIB);
hDIB = NULL;
SelectPalette(hDC, hPal, TRUE);
RealizePalette(hDC);
ReleaseDC(NULL, hDC);
return NULL;
}
bi = *lpbi;
// clean up
GlobalUnlock(hDIB);
SelectPalette(hDC, hPal, TRUE);
RealizePalette(hDC);
ReleaseDC(NULL, hDC);
// return handle to the DIB
return hDIB;
}
/*************************************************************************
*
* BitmapToDIB()
*
* Parameters:
*
* HBITMAP hBitmap - specifies the bitmap to convert
*
* HPALETTE hPal - specifies the palette to use with the bitmap
*
* WORD wBitCount - specifies the DIB colorbits
*
* Return Value:
*
* HDIB - identifies the device-dependent bitmap
*
* Description:
*
* This function creates a DIB from a bitmap using the specified palette.
*
************************************************************************/
HDIB BitmapToDIB(HBITMAP hBitmap, HPALETTE hPalette, WORD wBitCount)
{
HDIB hNewDib;
if (! hBitmap)
return NULL;
// get bitmap info
BITMAP bm; // bitmap structure
GetObject(hBitmap, sizeof(bm), (LPBYTE)&bm);
int biBits = bm.bmPlanes * bm.bmBitsPixel;
// make sure bits per pixel is valid
if (biBits <= 1)
biBits = 1;
else if (biBits <= 4)
biBits = 4;
else if (biBits <= 8)
biBits = 8;
else // if greater than 8-bit, force to 24-bit
biBits = 24;
// get DIB handle from current bitmap
HDIB hDib = BitmapToDIB(hBitmap, hPalette);
if (! hDib)
return NULL;
if (wBitCount == biBits)
hNewDib = hDib;
else
{
// DIB bits/pixel is not the same as device
// convert dib format to accordingly
hNewDib = ConvertDIBFormat(hDib, wBitCount, hPalette);
// cleanup hDib
GlobalFree(hDib);
}
return hNewDib;
}
/*************************************************************************
*
* ChangeBitmapFormat()
*
* Parameter:
*
* HBITMAP - handle to a bitmap
*
* WORD - desired bits per pixel
*
* DWORD - desired compression format
*
* HPALETTE - handle to palette
*
* Return Value:
*
* HDIB - handle to the new DIB if successful, else NULL
*
* Description:
*
* This function will convert a bitmap to the specified bits per pixel
* and compression format. The bitmap and it's palette will remain
* after calling this function.
*
************************************************************************/
HDIB ChangeBitmapFormat (HBITMAP hbm, WORD biBits, DWORD biCompression, HPALETTE hpal)
{
BITMAP bm;
BITMAPINFOHEADER bi;
LPBITMAPINFOHEADER lpbi;
DWORD dwLen;
HANDLE hdib;
HANDLE h;
HDC hdc;
if (!hbm)
return NULL;
if (hpal == NULL)
hpal = (HPALETTE)GetStockObject(DEFAULT_PALETTE);
GetObject(hbm,sizeof(bm),(LPBYTE)&bm);
if (biBits == 0)
{
biBits = bm.bmPlanes * bm.bmBitsPixel;
// make sure bits per pixel is valid
if (biBits <= 1)
biBits = 1;
else if (biBits <= 4)
biBits = 4;
else if (biBits <= 8)
biBits = 8;
else // if greater than 8-bit, force to 24-bit
biBits = 24;
}
bi.biSize = sizeof(BITMAPINFOHEADER);
bi.biWidth = bm.bmWidth;
bi.biHeight = bm.bmHeight;
bi.biPlanes = 1;
bi.biBitCount = biBits;
bi.biCompression = biCompression;
bi.biSizeImage = 0;
bi.biXPelsPerMeter = 0;
bi.biYPelsPerMeter = 0;
bi.biClrUsed = 0;
bi.biClrImportant = 0;
dwLen = bi.biSize + PaletteSize((LPBYTE)&bi);
hdc = GetDC(NULL);
HPALETTE hpalT = SelectPalette(hdc,hpal,FALSE);
RealizePalette(hdc);
hdib = GlobalAlloc(GHND,dwLen);
if (!hdib)
{
SelectPalette(hdc,hpalT,FALSE);
ReleaseDC(NULL,hdc);
return NULL;
}
lpbi = (LPBITMAPINFOHEADER)GlobalLock(hdib);
*lpbi = bi;
/* call GetDIBits with a NULL lpBits param, so it will calculate the
* biSizeImage field for us
*/
GetDIBits(hdc, hbm, 0L, (DWORD)bi.biHeight,
(LPBYTE)NULL, (LPBITMAPINFO)lpbi, (DWORD)DIB_RGB_COLORS);
bi = *lpbi;
GlobalUnlock(hdib);
/* If the driver did not fill in the biSizeImage field, make one up */
if (bi.biSizeImage == 0)
{
bi.biSizeImage = WIDTHBYTES((DWORD)bm.bmWidth * biBits) * bm.bmHeight;
if (biCompression != BI_RGB)
bi.biSizeImage = (bi.biSizeImage * 3) / 2;
}
/* realloc the buffer big enough to hold all the bits */
dwLen = bi.biSize + PaletteSize((LPBYTE)&bi) + bi.biSizeImage;
if (h = GlobalReAlloc(hdib,dwLen,0))
hdib = h;
else
{
GlobalFree(hdib);
hdib = NULL;
SelectPalette(hdc,hpalT,FALSE);
ReleaseDC(NULL,hdc);
return hdib;
}
/* call GetDIBits with a NON-NULL lpBits param, and actualy get the
* bits this time
*/
lpbi = (LPBITMAPINFOHEADER)GlobalLock(hdib);
if (! GetDIBits(hdc,
hbm,
0L,
(DWORD)bi.biHeight,
(LPBYTE)lpbi + (WORD)lpbi->biSize + PaletteSize((LPBYTE)lpbi),
(LPBITMAPINFO)lpbi,
(DWORD)DIB_RGB_COLORS))
{
GlobalUnlock(hdib);
hdib = NULL;
SelectPalette(hdc,hpalT,FALSE);
ReleaseDC(NULL,hdc);
return NULL;
}
bi = *lpbi;
GlobalUnlock(hdib);
SelectPalette(hdc,hpalT,FALSE);
ReleaseDC(NULL,hdc);
return hdib;
}
/*************************************************************************
*
* ChangeDIBFormat()
*
* Parameter:
*
* HDIB - handle to packed-DIB in memory
*
* WORD - desired bits per pixel
*
* DWORD - desired compression format
*
* Return Value:
*
* HDIB - handle to the new DIB if successful, else NULL
*
* Description:
*
* This function will convert the bits per pixel and/or the compression
* format of the specified DIB. Note: If the conversion was unsuccessful,
* we return NULL. The original DIB is left alone. Don't use code like the
* following:
*
* hMyDIB = ChangeDIBFormat(hMyDIB, 8, BI_RLE4);
*
* The conversion will fail, but hMyDIB will now be NULL and the original
* DIB will now hang around in memory. We could have returned the old
* DIB, but we wanted to allow the programmer to check whether this
* conversion succeeded or failed.
*
************************************************************************/
HDIB ChangeDIBFormat(HDIB hDIB, WORD wBitCount, DWORD dwCompression)
{
HBITMAP hBitmap; // Handle to bitmap
HDIB hNewDIB = NULL; // Handle to new DIB
HPALETTE hPal; // Handle to palette
// Check for a valid DIB handle
if (!hDIB)
return NULL;
// Save the old DIB's palette
hPal = CreateDIBPalette(hDIB);
if (hPal == NULL)
hPal = (HPALETTE)GetStockObject(DEFAULT_PALETTE);
// Convert old DIB to a bitmap
hBitmap = DIBToBitmap(hDIB, hPal);
if (!hBitmap)
{
DeleteObject(hPal);
return NULL;
}
// Change bitmap format
hNewDIB = ChangeBitmapFormat(hBitmap, wBitCount, dwCompression, hPal);
// Clean up and return
DeleteObject(hBitmap);
DeleteObject(hPal);
return hNewDIB;
}
/****************************************************************************
*
* FUNCTION: ConvertDIBFormat
*
* PURPOSE: Creates a new DIB of the requested format, copies the source
* image to the new DIB.
*
* PARAMS: LPBITMAPINFO lpSrcDIB - the source CF_DIB
* UINT nWidth - width for new DIB
* UINT nHeight - height for new DIB
* UINT nbpp - bpp for new DIB
* BOOL bStretch - TRUE to stretch source to dest
* FALSE to take upper left of image
* HPALETTE hPalSrc - Palette used to set new DIB
* DWORD dwSize - return the size of new DIB pointer
*
* RETURNS: HDIB - Handle of CF_DIB memory block with new image
* NULL on failure
*
\****************************************************************************/
HDIB ConvertDIBFormat(LPBYTE lpDIB, UINT nWidth, UINT nHeight, UINT nbpp, BOOL bStretch, HPALETTE hPalSrc)
{
LPBITMAPINFO lpSrcDIB = (LPBITMAPINFO)lpDIB;
LPBITMAPINFO lpbmi = NULL;
LPBYTE lpSourceBits, lpTargetBits, lpResult;
HDC hDC = NULL, hSourceDC, hTargetDC;
HBITMAP hSourceBitmap, hTargetBitmap, hOldTargetBitmap, hOldSourceBitmap;
DWORD dwSourceBitsSize, dwTargetBitsSize, dwTargetHeaderSize, dwColorNum;
HDIB hDib;
// Allocate and fill out a BITMAPINFO struct for the new DIB
if (nbpp <= 8)
dwColorNum = 1 << nbpp;
else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -