📄 imagecls.cpp
字号:
// Get the current window title.
GetWindowText( hWnd, szBuffer, SZBUFFER_SIZE );
// Fill in a DIB header structure for the current bitmap.
DibInfo(hbiCurrent, &bi);
// If we currently have a clipping rectangle, set the bitmap dimensions
// to those of the clipping rectangle.
if (!IsRectEmpty(&rcClip)) {
bi.biWidth = rcClip.right - rcClip.left;
bi.biHeight = rcClip.bottom - rcClip.top;
}
// Get a device context handle for the printer.
if (!(hDC = GetPrinterDC())) return;
// Get the dimensions and resolution of the printable area
// of the printer.
xSize = GetDeviceCaps(hDC, HORZRES);
ySize = GetDeviceCaps(hDC, VERTRES);
xRes = GetDeviceCaps(hDC, LOGPIXELSX);
yRes = GetDeviceCaps(hDC, LOGPIXELSY);
// Set half inch margins on the left and right, and a one inch
// margin on the top of the page, maintaining the correct
// aspect ratio.
dx = xSize - xRes;
dy = (int)((long)dx * bi.biHeight/bi.biWidth);
// Set the bounding rectangle for the picture.
Rect.top = yRes;
Rect.left = xRes / 2;
Rect.bottom = yRes + dy;
Rect.right = xRes / 2 + dx;
// and tell the printer driver.
Escape(hDC, SET_BOUNDS, sizeof(RECT), (LPSTR)&Rect, NULL);
// Finally, print the image.
if (InitPrinting( hDC, hWnd, hInst, szBuffer )) {
PrintDIB( hWnd, hDC, xRes/2, yRes, dx, dy );
Escape (hDC, NEWFRAME, NULL, NULL, NULL);
TermPrinting(hDC);
}
// Delete the printer DC.
DeleteDC(hDC);
}
#endif
// IdentifyFileFormat
// Identify the format of a file.
void ImageClass::IdentifyFileFormat()
{
// Assume initially that we have a DIB file.
nFileFormat = FI_DIB;
// First, just look at the extension.
if (_fstrstr(achFileName,".GIF"))
nFileFormat = FI_GIF;
}
// ImageClass::ReadDibBitmapInfo
// Read a file in DIB format and set up global memory for its BITMAPINFO.
// This function will work with both "old" (BITMAPCOREINFO) and "new"
// (BITMAPINFOHEADER) DIB formats, but will always return a "new" BITMAPINFO.
HANDLE ImageClass::ReadDibBitmapInfo ( int fh )
// Input arguments:
// fh Handle to DIB file.
{
DWORD off;
HANDLE hbi = NULL;
int size;
int i;
WORD nNumColors;
RGBQUAD FAR *pRgb;
BITMAPINFOHEADER bi;
BITMAPCOREHEADER bc;
LPBITMAPINFOHEADER lpbi;
BITMAPFILEHEADER bf;
DWORD dwWidth = 0;
DWORD dwHeight = 0;
WORD wPlanes, wBitCount;
if (fh == -1)
return NULL;
/* Reset file pointer and read file header */
off = _llseek(fh, 0L, SEEK_CUR);
if (sizeof (bf) != _lread (fh, (LPSTR)&bf, sizeof (bf)))
return FALSE;
/* Do we have a RC HEADER? */
if (!ISDIB (bf.bfType)) {
bf.bfOffBits = 0L;
_llseek (fh, off, SEEK_SET);
}
if (sizeof (bi) != _lread (fh, (LPSTR)&bi, sizeof(bi)))
return FALSE;
nNumColors = DibNumColors (&bi);
/* Check the nature (BITMAPINFO or BITMAPCORE) of the info. block
* and extract the field information accordingly. If a BITMAPCOREHEADER,
* transfer it's field information to a BITMAPINFOHEADER-style block
*/
switch (size = (int)bi.biSize){
case sizeof (BITMAPINFOHEADER):
break;
case sizeof (BITMAPCOREHEADER):
bc = *(BITMAPCOREHEADER*)&bi;
dwWidth = (DWORD)bc.bcWidth;
dwHeight = (DWORD)bc.bcHeight;
wPlanes = bc.bcPlanes;
wBitCount = bc.bcBitCount;
bi.biSize = sizeof(BITMAPINFOHEADER);
bi.biWidth = dwWidth;
bi.biHeight = dwHeight;
bi.biPlanes = wPlanes;
bi.biBitCount = wBitCount;
bi.biCompression = BI_RGB;
bi.biSizeImage = 0;
bi.biXPelsPerMeter = 0;
bi.biYPelsPerMeter = 0;
bi.biClrUsed = nNumColors;
bi.biClrImportant = nNumColors;
_llseek (fh, (LONG)sizeof (BITMAPCOREHEADER) - sizeof (BITMAPINFOHEADER), SEEK_CUR);
break;
default:
/* Not a DIB! */
return NULL;
}
/* Fill in some default values if they are zero */
if (bi.biSizeImage == 0){
bi.biSizeImage = WIDTHBYTES ((DWORD)bi.biWidth * bi.biBitCount)
* bi.biHeight;
}
if (bi.biClrUsed == 0)
bi.biClrUsed = DibNumColors(&bi);
/* Allocate for the BITMAPINFO structure and the color table. */
hbi = GlobalAlloc (GHND, (LONG)bi.biSize + nNumColors * sizeof(RGBQUAD));
if (!hbi)
return NULL;
lpbi = (LPBITMAPINFOHEADER) (VOID FAR *)GlobalLock (hbi);
*lpbi = bi;
/* Get a pointer to the color table */
pRgb = (RGBQUAD FAR *)((LPSTR)lpbi + bi.biSize);
if (nNumColors){
if (size == sizeof(BITMAPCOREHEADER)){
/* Convert a old color table (3 byte RGBTRIPLEs) to a new
* color table (4 byte RGBQUADs)
*/
_lread (fh, (LPSTR)pRgb, nNumColors * sizeof(RGBTRIPLE));
for (i = nNumColors - 1; i >= 0; i--){
RGBQUAD rgb;
rgb.rgbRed = ((RGBTRIPLE FAR *)pRgb)[i].rgbtRed;
rgb.rgbBlue = ((RGBTRIPLE FAR *)pRgb)[i].rgbtBlue;
rgb.rgbGreen = ((RGBTRIPLE FAR *)pRgb)[i].rgbtGreen;
rgb.rgbReserved = (BYTE)0;
pRgb[i] = rgb;
}
}
else
_lread(fh,(LPSTR)pRgb,nNumColors * sizeof(RGBQUAD));
}
if (bf.bfOffBits != 0L)
_llseek(fh,off + bf.bfOffBits,SEEK_SET);
GlobalUnlock(hbi);
return hbi;
}
// ImageClass::DibInfo
// Retrieve the DIB information associated with a CF_DIB format memory block.
BOOL ImageClass::DibInfo ( HANDLE hbi, LPBITMAPINFOHEADER lpbi )
// Input arguments:
// hbi Handle to the BITMAPINFO.
//
// Output arguments:
// lpbi Filled in BITMAPINFOHEADER structure.
{
if (hbi){
*lpbi = *(LPBITMAPINFOHEADER)GlobalLock (hbi);
/* fill in the default fields */
if (lpbi->biSize != sizeof (BITMAPCOREHEADER)){
if (lpbi->biSizeImage == 0L)
lpbi->biSizeImage =
WIDTHBYTES(lpbi->biWidth*lpbi->biBitCount) * lpbi->biHeight;
if (lpbi->biClrUsed == 0L)
lpbi->biClrUsed = DibNumColors (lpbi);
}
GlobalUnlock (hbi);
return TRUE;
}
return FALSE;
}
// ImageClass::CreateBIPalette
// Given a pointer to a BITMAPINFO structure, create a GDI palette object
// from the colour table.
HPALETTE ImageClass::CreateBIPalette ( LPBITMAPINFOHEADER lpbi )
{
LOGPALETTE *pPal;
HPALETTE hpal = NULL;
WORD nNumColors;
BYTE red;
BYTE green;
BYTE blue;
WORD i;
RGBQUAD FAR *pRgb;
if (!lpbi)
return NULL;
if (lpbi->biSize != sizeof(BITMAPINFOHEADER))
return NULL;
/* Get a pointer to the color table and the number of colors in it */
pRgb = (RGBQUAD FAR *)((LPSTR)lpbi + (WORD)lpbi->biSize);
nNumColors = DibNumColors(lpbi);
if (nNumColors){
/* Allocate for the logical palette structure */
pPal = (LOGPALETTE*)LocalAlloc(LPTR,sizeof(LOGPALETTE) + nNumColors * sizeof(PALETTEENTRY));
if (!pPal)
return NULL;
pPal->palNumEntries = nNumColors;
pPal->palVersion = PALVERSION;
/* Fill in the palette entries from the DIB color table and
* create a logical color palette.
*/
for (i = 0; i < nNumColors; i++){
pPal->palPalEntry[i].peRed = pRgb[i].rgbRed;
pPal->palPalEntry[i].peGreen = pRgb[i].rgbGreen;
pPal->palPalEntry[i].peBlue = pRgb[i].rgbBlue;
pPal->palPalEntry[i].peFlags = (BYTE)0;
}
hpal = CreatePalette(pPal);
LocalFree((HANDLE)pPal);
}
else if (lpbi->biBitCount == 24){
/* A 24 bitcount DIB has no color table entries so, set the number of
* to the maximum value (256).
*/
nNumColors = MAXPALETTE;
pPal = (LOGPALETTE*)LocalAlloc(LPTR,sizeof(LOGPALETTE) + nNumColors * sizeof(PALETTEENTRY));
if (!pPal)
return NULL;
pPal->palNumEntries = nNumColors;
pPal->palVersion = PALVERSION;
red = green = blue = 0;
/* Generate 256 (= 8*8*4) RGB combinations to fill the palette
* entries.
*/
for (i = 0; i < pPal->palNumEntries; i++){
pPal->palPalEntry[i].peRed = red;
pPal->palPalEntry[i].peGreen = green;
pPal->palPalEntry[i].peBlue = blue;
pPal->palPalEntry[i].peFlags = (BYTE)0;
if (!(red += 32))
if (!(green += 32))
blue += 64;
}
hpal = CreatePalette(pPal);
LocalFree((HANDLE)pPal);
}
return hpal;
}
// ImageClass::CreateDibPalette
// Given a handle to a BITMAPINFO structure, create a GDI palette object
// from the colour table.
HPALETTE ImageClass::CreateDibPalette ( HANDLE hbi )
{
HPALETTE hpal;
if (!hbi)
return NULL;
hpal = CreateBIPalette((LPBITMAPINFOHEADER)GlobalLock(hbi));
GlobalUnlock(hbi);
return hpal;
}
/****************************************************************************
* *
* FUNCTION :OpenDIB(LPSTR szFile) *
* *
* PURPOSE :Open a DIB file and create a MEMORY DIB, a memory handle *
* containing BITMAPINFO, palette data and the bits. *
* *
* RETURNS :A handle to the DIB. *
* *
****************************************************************************/
// ImageClass::OpenDIB
// Open a DIB file and create a memory DIB; a memory block containing
// BITMAPINFO, palette data, and the image bits.
HANDLE ImageClass::OpenDIB ()
{
unsigned fh;
BITMAPINFOHEADER bi;
LPBITMAPINFOHEADER lpbi;
DWORD dwLen = 0;
DWORD dwBits;
HANDLE hdib;
HANDLE h;
OFSTRUCT of;
/* Open the file and read the DIB information */
fh = OpenFile( achFileName, &of, OF_READ );
if (fh == -1)
return NULL;
hdib = ReadDibBitmapInfo(fh);
if (!hdib)
return NULL;
DibInfo(hdib,&bi);
/* Calculate the memory needed to hold the DIB */
dwBits = bi.biSizeImage;
dwLen = bi.biSize + (DWORD)PaletteSize (&bi) + dwBits;
/* Try to increase the size of the bitmap info. buffer to hold the DIB */
h = GlobalReAlloc(hdib, dwLen, GHND);
if (!h){
GlobalFree(hdib);
hdib = NULL;
}
else
hdib = h;
/* Read in the bits */
if (hdib){
lpbi = (LPBITMAPINFOHEADER) (VOID FAR *)GlobalLock(hdib);
lread(fh, (LPSTR)lpbi + (WORD)lpbi->biSize + PaletteSize(lpbi), dwBits);
GlobalUnlock(hdib);
}
_lclose(fh);
return hdib;
}
// ImageClass::PaletteSize
// Return the size of a DIB palette, in bytes.
WORD ImageClass::PaletteSize( VOID FAR *pv )
{
LPBITMAPINFOHEADER lpbi;
WORD NumColors;
lpbi = (LPBITMAPINFOHEADER)pv;
NumColors = DibNumColors(lpbi);
if (lpbi->biSize == sizeof(BITMAPCOREHEADER))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -