📄 dibapi.cpp
字号:
// Check to see if we're dealing with an OS/2 DIB. If so, don't
// save it because our functions aren't written to deal with these
// DIBs.
if (lpBI->biSize != sizeof(BITMAPINFOHEADER))
{
GlobalUnlock(hDib);
CloseHandle(fh);
return FALSE;
}
// Fill in the fields of the file header
// Fill in file type (first 2 bytes must be "BM" for a bitmap)
bmfHdr.bfType = DIB_HEADER_MARKER; // "BM"
dwDIBSize = *(LPDWORD)lpBI + PaletteSize((LPBYTE)lpBI);
// Now calculate the size of the image
// It's an RLE bitmap, we can't calculate size, so trust the biSizeImage
// field
if ((lpBI->biCompression == BI_RLE8) || (lpBI->biCompression == BI_RLE4))
dwDIBSize += lpBI->biSizeImage;
else
{
DWORD dwBmBitsSize; // Size of Bitmap Bits only
// It's not RLE, so size is Width (DWORD aligned) * Height
dwBmBitsSize = WIDTHBYTES((lpBI->biWidth)*((DWORD)lpBI->biBitCount)) *
lpBI->biHeight;
dwDIBSize += dwBmBitsSize;
// Now, since we have calculated the correct size, why don't we
// fill in the biSizeImage field (this will fix any .BMP files which
// have this field incorrect).
lpBI->biSizeImage = dwBmBitsSize;
}
// Calculate the file size by adding the DIB size to sizeof(BITMAPFILEHEADER)
bmfHdr.bfSize = dwDIBSize + sizeof(BITMAPFILEHEADER);
bmfHdr.bfReserved1 = 0;
bmfHdr.bfReserved2 = 0;
// Now, calculate the offset the actual bitmap bits will be in
// the file -- It's the Bitmap file header plus the DIB header,
// plus the size of the color table.
bmfHdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + lpBI->biSize +
PaletteSize((LPBYTE)lpBI);
// Write the file header
WriteFile(fh, (LPBYTE)&bmfHdr, sizeof(BITMAPFILEHEADER), &dwWritten, NULL);
// Write the DIB header and the bits -- use local version of
// MyWrite, so we can write more than 32767 bytes of data
WriteFile(fh, (LPBYTE)lpBI, dwDIBSize, &dwWritten, NULL);
GlobalUnlock(hDib);
if (dwWritten == 0)
return FALSE; // oops, something happened in the write
else
return TRUE; // Success code
}
LPBYTE FindDIBBits(LPBYTE lpDIB)
{
return (lpDIB + *(LPDWORD)lpDIB + PaletteSize(lpDIB));
}
DWORD DIBWidth(LPBYTE lpDIB)
{
LPBITMAPINFOHEADER lpbmi; // pointer to a Win 3.0-style DIB
LPBITMAPCOREHEADER lpbmc; // pointer to an OS/2-style DIB
// point to the header (whether Win 3.0 and OS/2)
lpbmi = (LPBITMAPINFOHEADER)lpDIB;
lpbmc = (LPBITMAPCOREHEADER)lpDIB;
// return the DIB width if it is a Win 3.0 DIB
if (lpbmi->biSize == sizeof(BITMAPINFOHEADER))
return lpbmi->biWidth;
else // it is an OS/2 DIB, so return its width
return (DWORD)lpbmc->bcWidth;
}
DWORD DIBWidth(HDIB hDIB)
{
LPBYTE lpDIB = (LPBYTE)GlobalLock(hDIB);
DWORD dw = DIBWidth(lpDIB);
GlobalUnlock(hDIB);
return dw;
}
DWORD DIBHeight(LPBYTE lpDIB)
{
LPBITMAPINFOHEADER lpbmi; // pointer to a Win 3.0-style DIB
LPBITMAPCOREHEADER lpbmc; // pointer to an OS/2-style DIB
// point to the header (whether OS/2 or Win 3.0
lpbmi = (LPBITMAPINFOHEADER)lpDIB;
lpbmc = (LPBITMAPCOREHEADER)lpDIB;
// return the DIB height if it is a Win 3.0 DIB
if (lpbmi->biSize == sizeof(BITMAPINFOHEADER))
return lpbmi->biHeight;
else // it is an OS/2 DIB, so return its height
return (DWORD)lpbmc->bcHeight;
}
DWORD DIBHeight(HDIB hDIB)
{
LPBYTE lpDIB = (LPBYTE)GlobalLock(hDIB);
DWORD dw = DIBHeight(lpDIB);
GlobalUnlock(hDIB);
return dw;
}
WORD PaletteSize(LPBYTE lpDIB)
{
// calculate the size required by the palette
if (IS_WIN30_DIB (lpDIB))
return (DIBNumColors(lpDIB) * sizeof(RGBQUAD));
else
return (DIBNumColors(lpDIB) * sizeof(RGBTRIPLE));
}
WORD PaletteSize(HDIB hDIB)
{
LPBYTE lpDIB = (LPBYTE)GlobalLock(hDIB);
WORD wSize = PaletteSize(lpDIB);
GlobalUnlock(hDIB);
return wSize;
}
WORD DIBNumColors(LPBYTE lpDIB)
{
WORD wBitCount; // DIB bit count
// If this is a Windows-style DIB, the number of colors in the
// color table can be less than the number of bits per pixel
// allows for (i.e. lpbi->biClrUsed can be set to some value).
// If this is the case, return the appropriate value.
if (IS_WIN30_DIB(lpDIB))
{
DWORD dwClrUsed;
dwClrUsed = ((LPBITMAPINFOHEADER)lpDIB)->biClrUsed;
if (dwClrUsed)
return (WORD)dwClrUsed;
}
// Calculate the number of colors in the color table based on
// the number of bits per pixel for the DIB.
if (IS_WIN30_DIB(lpDIB))
wBitCount = ((LPBITMAPINFOHEADER)lpDIB)->biBitCount;
else
wBitCount = ((LPBITMAPCOREHEADER)lpDIB)->bcBitCount;
// return number of colors based on bits per pixel
switch (wBitCount)
{
case 1:
return 2;
case 4:
return 16;
case 8:
return 256;
default:
return 0;
}
}
WORD DIBNumColors(HDIB hDIB)
{
LPBYTE lpDIB = (LPBYTE)GlobalLock(hDIB);
WORD wSize = DIBNumColors(lpDIB);
GlobalUnlock(hDIB);
return wSize;
}
WORD DIBBitCount(LPBYTE lpDIB)
{
if (IS_WIN30_DIB(lpDIB))
return ((LPBITMAPINFOHEADER)lpDIB)->biBitCount;
else
return ((LPBITMAPCOREHEADER)lpDIB)->bcBitCount;
}
WORD DIBBitCount(HDIB hDIB)
{
LPBYTE lpDIB = (LPBYTE)GlobalLock(hDIB);
WORD wSize = DIBBitCount(lpDIB);
GlobalUnlock(hDIB);
return wSize;
}
DWORD BytesPerLine(LPBYTE lpDIB)
{
return WIDTHBYTES(((LPBITMAPINFOHEADER)lpDIB)->biWidth * ((LPBITMAPINFOHEADER)lpDIB)->biPlanes * ((LPBITMAPINFOHEADER)lpDIB)->biBitCount);
}
DWORD BytesPerLine(HDIB hDIB)
{
LPBYTE lpDIB = (LPBYTE)GlobalLock(hDIB);
DWORD dw = BytesPerLine(lpDIB);
GlobalUnlock(hDIB);
return dw;
}
DWORD DIBlockSize(LPBYTE lpDIB)
{
if (((LPBITMAPINFOHEADER)lpDIB)->biSizeImage == 0)
((LPBITMAPINFOHEADER)lpDIB)->biSizeImage = BytesPerLine(lpDIB) * ((LPBITMAPINFOHEADER)lpDIB)->biHeight;
return ((LPBITMAPINFOHEADER)lpDIB)->biSize + PaletteSize(lpDIB) + ((LPBITMAPINFOHEADER)lpDIB)->biSizeImage;
}
DWORD DIBlockSize(HDIB hDIB)
{
LPBYTE lpDIB = (LPBYTE)GlobalLock(hDIB);
DWORD dw = DIBlockSize(lpDIB);
GlobalUnlock(hDIB);
return dw;
}
HPALETTE CreateDIBPalette(LPBYTE lpbi)
{
LPLOGPALETTE lpPal; // pointer to a logical palette
HANDLE hLogPal; // handle to a logical palette
HPALETTE hPal = NULL; // handle to a palette
int i, wNumColors; // loop index, number of colors in color table
LPBITMAPINFO lpbmi; // pointer to BITMAPINFO structure (Win3.0)
LPBITMAPCOREINFO lpbmc; // pointer to BITMAPCOREINFO structure (OS/2)
BOOL bWinStyleDIB; // Win3.0 DIB?
// if handle to DIB is invalid, return NULL
if (! lpbi)
return NULL;
// get pointer to BITMAPINFO (Win 3.0)
lpbmi = (LPBITMAPINFO)lpbi;
// get pointer to BITMAPCOREINFO (OS/2 1.x)
lpbmc = (LPBITMAPCOREINFO)lpbi;
// get the number of colors in the DIB
wNumColors = DIBNumColors(lpbi);
// is this a Win 3.0 DIB?
bWinStyleDIB = IS_WIN30_DIB(lpbi);
if (wNumColors)
{
// allocate memory block for logical palette
hLogPal = GlobalAlloc(GHND, sizeof(LOGPALETTE) +
sizeof(PALETTEENTRY) * wNumColors);
// if not enough memory, clean up and return NULL
if (!hLogPal)
return NULL;
// lock memory block and get pointer to it
lpPal = (LPLOGPALETTE)GlobalLock(hLogPal);
// set version and number of palette entries
lpPal->palVersion = PALVERSION;
lpPal->palNumEntries = wNumColors;
// store RGB triples (if Win 3.0 DIB) or RGB quads (if OS/2 DIB)
// into palette
for (i = 0; i < wNumColors; i++)
{
if (bWinStyleDIB)
{
lpPal->palPalEntry[i].peRed = lpbmi->bmiColors[i].rgbRed;
lpPal->palPalEntry[i].peGreen = lpbmi->bmiColors[i].rgbGreen;
lpPal->palPalEntry[i].peBlue = lpbmi->bmiColors[i].rgbBlue;
lpPal->palPalEntry[i].peFlags = 0;
}
else
{
lpPal->palPalEntry[i].peRed = lpbmc->bmciColors[i].rgbtRed;
lpPal->palPalEntry[i].peGreen = lpbmc->bmciColors[i].rgbtGreen;
lpPal->palPalEntry[i].peBlue = lpbmc->bmciColors[i].rgbtBlue;
lpPal->palPalEntry[i].peFlags = 0;
}
}
// create the palette and get handle to it
hPal = CreatePalette(lpPal);
// cleanup
GlobalUnlock(hLogPal);
GlobalFree(hLogPal);
}
// return handle to DIB's palette
return hPal;
}
HPALETTE CreateDIBPalette(HDIB hDIB)
{
HPALETTE hPal = NULL; // handle to a palette
LPBYTE lpbi; // pointer to packed-DIB
// if handle to DIB is invalid, return NULL
if (!hDIB)
return NULL;
// lock DIB memory block and get a pointer to it
lpbi = (LPBYTE)GlobalLock(hDIB);
hPal = CreateDIBPalette(lpbi);
// Unlock hDIB
GlobalUnlock(hDIB);
// return handle to DIB's palette
return hPal;
}
HBITMAP DIBToBitmap(HDIB hDIB, HPALETTE hPal)
{
LPBYTE lpDIBHdr, lpDIBBits; // pointer to DIB header, pointer to DIB bits
HBITMAP hBitmap; // handle to device-dependent bitmap
HDC hDC; // handle to DC
HPALETTE hOldPal = NULL; // handle to a palette
// if invalid handle, return NULL
if (!hDIB)
return NULL;
// lock memory block and get a pointer to it
lpDIBHdr = (LPBYTE)GlobalLock(hDIB);
// get a pointer to the DIB bits
lpDIBBits = FindDIBBits(lpDIBHdr);
// get a DC
hDC = GetDC(NULL);
if (!hDC)
{
// clean up and return NULL
GlobalUnlock(hDIB);
return NULL;
}
// select and realize palette
if (hPal)
{
hOldPal = SelectPalette(hDC, hPal, FALSE);
RealizePalette(hDC);
}
// create bitmap from DIB info and bits
hBitmap = CreateDIBitmap(hDC,
(LPBITMAPINFOHEADER)lpDIBHdr,
CBM_INIT,
lpDIBBits,
(LPBITMAPINFO)lpDIBHdr,
DIB_RGB_COLORS);
// restore previous palette
if (hOldPal)
SelectPalette(hDC, hOldPal, FALSE);
// clean up
ReleaseDC(NULL, hDC);
GlobalUnlock(hDIB);
// return handle to the bitmap
return hBitmap;
}
HDIB BitmapToDIB(HBITMAP hBitmap, HPALETTE hPal)
{
BITMAP bm; // bitmap structure
BITMAPINFOHEADER bi; // bitmap header
LPBITMAPINFOHEADER lpbi; // pointer to BITMAPINFOHEADER
DWORD dwLen; // size of memory block
HANDLE hDIB, h; // handle to DIB, temp handle
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -