dibapi.cpp

来自「一个非常全的vc编程的原程序代码是关于图像处理的!」· C++ 代码 · 共 2,454 行 · 第 1/5 页

CPP
2,454
字号
	
	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;
	}
	
	lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDib);
	if(!GetDIBits(	hDC,
					hBitmap,
					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;
}
/*************************************************
convert  the bits per pixel and/or the compression
format of the specified DIB.
parameter:  HDIB, WORD(wBitCount), WORD(dwCompression)
return:     HDIB
*************************************************/
HDIB ChangeDIBFormat(HDIB hDib,WORD wBitCount,DWORD dwCompression)
{
	HBITMAP		hBitmap;
	HDIB		hNewDib = NULL;
	HPALETTE	hPal;

	if(!hDib)
		return NULL;
	
	hPal = CreateDIBPalette(hDib);
	if(hPal == NULL)
		hPal = (HPALETTE)GetStockObject(DEFAULT_PALETTE);
	
	hBitmap = DIBToBitmap(hDib, hPal);
	if(!hBitmap)
	{
		DeleteObject(hPal);
		return NULL;
	}
	
	hNewDib = ChangeBitmapFormat(hBitmap, wBitCount, dwCompression, hPal);
	
	DeleteObject(hBitmap);
	DeleteObject(hPal);

	return hNewDib;
}
/**************************************************************
copy one palette to another palette.
parameter:  HPALETTE
return:     HPALETTE
**************************************************************/
HPALETTE CopyPalette(HPALETTE hPalSrc)
{
	PLOGPALETTE pLogPal;
	int			iNumEntries=0;
	HPALETTE	hPal;
	HANDLE		h;

	iNumEntries = GetPaletteEntries(hPalSrc, 0, iNumEntries, NULL);
	if(iNumEntries == 0)
		return (HPALETTE)NULL;
	h = GlobalAlloc(GHND, sizeof(DWORD)+sizeof(PALETTEENTRY)*iNumEntries);
	if(!h)
		return (HPALETTE)NULL;
	pLogPal = (PLOGPALETTE)GlobalLock(h);
	if(!pLogPal)
		return (HPALETTE)NULL;
	pLogPal->palVersion = 0x300;
	pLogPal->palNumEntries = (WORD)iNumEntries;
	GetPaletteEntries(hPalSrc, 0, iNumEntries, pLogPal->palPalEntry);
	hPal = CreatePalette(pLogPal);

	GlobalUnlock(h);
	GlobalFree(h);

	return hPal;
}
/**************************************************************
create one palette identified with system.
parameter:  HPALETTE
return:     HPALETTE
**************************************************************/
HPALETTE CreateIdentifyPalette(HPALETTE hPalSrc)
{
	BOOL		bResult = FALSE;
	int			i, iSysColors, iPalEntries;
	HPALETTE	hPalette, hPalOld;

	if(!hPalSrc)
		return NULL;

	hPalette = CopyPalette(hPalSrc);

	HDC hDCScreen = GetDC(NULL);
	ASSERT(hDCScreen);
	if(!(GetDeviceCaps(hDCScreen, RASTERCAPS) & RC_PALETTE))
	{
		TRACE("not a palettized device");
		goto abort;
	}
    
	iSysColors = GetDeviceCaps(hDCScreen, NUMCOLORS);
	iPalEntries = GetDeviceCaps(hDCScreen, SIZEPALETTE);

	if(iSysColors > 256) goto abort;
	
	SetSystemPaletteUse(hDCScreen, SYSPAL_NOSTATIC);
	SetSystemPaletteUse(hDCScreen, SYSPAL_STATIC);
	
	hPalOld = SelectPalette(hDCScreen, hPalette, FALSE);
	RealizePalette(hDCScreen);
	
	SelectPalette(hDCScreen, hPalOld, FALSE);
	
	PALETTEENTRY pe[256];
	GetSystemPaletteEntries(hDCScreen, 0, iPalEntries, pe);
	
	for(i=0;i<iSysColors/2;i++)
		pe[i].peFlags = 0;
	for(;i<iPalEntries-iSysColors/2;i++)
		pe[i].peFlags = PC_NOCOLLAPSE;
	for(;i<iPalEntries;i++)
		pe[i].peFlags = 0;
	
	ResizePalette(hPalette, iPalEntries);
	
	SetPaletteEntries(hPalette, 0, iPalEntries, pe);
	bResult = TRUE;
abort:
	ReleaseDC(NULL, hDCScreen);
	return bResult? hPalette:NULL;
}
/***********************************************************
dispaly a palette.
parameter:     HDC, LPRECT, HPALETTE
return:        BOOL
************************************************************/
BOOL DisplayPalette(HDC hDC, LPRECT lpRect, HPALETTE hPal)
{
	if(!hPal)
		return FALSE;
	int nEntries;
	PALETTEENTRY pe[256];
	nEntries = GetPaletteEntries(hPal, 0, 256, pe);
	int nSqr = (int)sqrt((double)nEntries);

	int nWidth	= (lpRect->right-lpRect->left)/nSqr;
	int nHeight = (lpRect->bottom-lpRect->top)/nSqr;
	lpRect->right	= lpRect->left+nWidth*nSqr;
	lpRect->bottom	= lpRect->top+nHeight*nSqr;

	HPALETTE hOldPal = (HPALETTE)SelectPalette(hDC, hPal, FALSE);
	HBRUSH hBrush, hOldBrush;
	int x, y;

	for(int i=0;i<nEntries;i++)
	{
		x = i&nSqr;
		y = i/nSqr;
		hBrush = CreateSolidBrush(RGB(pe[i].peRed, pe[i].peGreen, pe[i].peBlue));
		hOldBrush = (HBRUSH)SelectObject(hDC, hBrush);
		Rectangle(hDC, lpRect->left+x*nWidth, lpRect->top+y*nHeight,
					lpRect->left+(x+1)*nWidth,lpRect->top+(y+1)*nHeight);
		SelectObject(hDC, hOldBrush);
		DeleteObject(hBrush);
	}
	SelectPalette(hDC, hOldPal, FALSE);
	return TRUE;
}
/******************************************************
get device palette used now.
parameter:   void
return:      HPALETTE
******************************************************/
HPALETTE  GetSystemPalette(void)
{
	HDC				hDC;
	static HPALETTE hPal = NULL;
	HANDLE			hLogPal;
	LPLOGPALETTE	lpLogPal;
	int				nColors;
	
	hDC = GetDC(NULL);
	if(!hDC)
		return NULL;

	nColors = PalEntriesOnDevice(hDC);
	hLogPal = GlobalAlloc(GHND, sizeof(LOGPALETTE)+nColors*sizeof(PALETTEENTRY));
	if(!hLogPal)
		return NULL;
	
	lpLogPal = (LPLOGPALETTE)GlobalLock(hLogPal);
	lpLogPal->palVersion = PALVERSION;
	lpLogPal->palNumEntries = nColors;
	
	GetSystemPaletteEntries(hDC, 0, nColors, (LPPALETTEENTRY)(lpLogPal->palPalEntry));
	
	hPal = CreatePalette(lpLogPal);
	
	GlobalUnlock(hLogPal);
	GlobalFree(hLogPal);
	ReleaseDC(NULL, hDC);

	return hPal;
}

/***************************************************
Map the colors in a DIB to a given palette.
parameter:     HDIB(source), HPALETTE(target)
returnL:       BOOL
***************************************************/
BOOL MapDIBColorsToPalette(HDIB hDib, HPALETTE hPalette)
{
	if(!hDib)
		return FALSE;
	if(!hPalette)
		return FALSE;

	LPBITMAPINFOHEADER lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDib);
	if(!lpbi)
	{
		GlobalUnlock(hDib);
		return FALSE;
	}
	LPRGBQUAD pctThis = (LPRGBQUAD)((LPBYTE)lpbi+lpbi->biSize);

	BYTE imap[256];
	for(int i=0;i<256;i++)
	{
		imap[i] = (BYTE)GetNearestPaletteIndex(hPalette, RGB(pctThis->rgbRed, pctThis->rgbGreen, pctThis->rgbBlue));
		pctThis ++;
	}
	
	LPBYTE pBits = (LPBYTE)lpbi+lpbi->biSize+PaletteSize((LPBYTE)lpbi);
	int iSize = WIDTHBYTES(lpbi->biBitCount*lpbi->biWidth)*lpbi->biHeight;
	while(iSize --)
	{
		*pBits = imap[*pBits];
		pBits ++;
	}
	
	PALETTEENTRY pe[256];
	GetPaletteEntries(hPalette, 0, 256, pe);
	pctThis = (LPRGBQUAD)((LPBYTE)lpbi+lpbi->biSize);
	for(i=0;i<256;i++)
	{
		pctThis->rgbRed	  = pe[i].peRed;
		pctThis->rgbGreen = pe[i].peGreen;
		pctThis->rgbBlue  = pe[i].peBlue;
		pctThis ++;
	}
	GlobalUnlock(hDib);
	return TRUE;
}
/***************************************************
copy the specified part of the screen to a debice-
dependent bimap.
parameter:   LPRECT(area wanted)
return:      HBITMAP
***************************************************/
HBITMAP CopyScreenToBitmap(LPRECT lpRect)
{
	HDC		hScrDC, hMemDC;
	HBITMAP hBitmap, hOldBitmap;
	int		nx, ny, nx2, ny2;
	int		nWidth, nHeight;
	int		xScrn, yScrn;

	if(IsRectEmpty(lpRect))
		return NULL;

	hScrDC = CreateDC("DISPLAY BITMAP", NULL, NULL, NULL);
	hMemDC = CreateCompatibleDC(hScrDC);
	
	nx  = lpRect->left;
	ny  = lpRect->top;
	nx2 = lpRect->right;
	ny2 = lpRect->bottom;
	
	xScrn = GetDeviceCaps(hScrDC, HORZRES);
	yScrn = GetDeviceCaps(hScrDC, VERTRES);
	
	if(nx < 0)
		nx = 0;
	if(ny < 0)
		ny = 0;
	if(nx2 > xScrn)
		nx2 = xScrn;
	if(ny2 > yScrn)
		ny2 = yScrn;
	nWidth  = nx2-nx;
	nHeight = ny2-ny;
	
	hBitmap = CreateCompatibleBitmap(hScrDC, nWidth, nHeight);
	
	hOldBitmap = (HBITMAP)SelectObject(hMemDC, hBitmap);
	 
	BitBlt(hMemDC, 0, 0, nWidth, nHeight, hScrDC, nx, ny, SRCCOPY);
	
	hBitmap = (HBITMAP)SelectObject(hMemDC, hOldBitmap);
	
	DeleteDC(hScrDC);
	DeleteDC(hMemDC);
	
	return hBitmap;
}
/*************************************************
copy the specified part of the window to a debice-
dependent bitmap.
parameter:  HWND,
			WORD(specified the area of window)
return:     HDIB
*************************************************/
HBITMAP CopyWindowToBitmap(HWND hWnd, WORD fPrintArea)
{
	HBITMAP hBitmap = NULL;
	if(!hWnd)
		return NULL;
	switch(fPrintArea)
	{
	case PW_WINDOW:
		{
			RECT rectWnd;
			GetWindowRect(hWnd, &rectWnd);
			hBitmap = CopyScreenToBitmap(&rectWnd);
			break;
		}

	case PW_CLIENT:
		{
			RECT  rectClient;
			POINT pt1, pt2;
		
			GetClientRect(hWnd, &rectClient);
			
			pt1.x = rectClient.left;
			pt1.y = rectClient.top;
			pt2.x = rectClient.right;
			pt2.y = rectClient.bottom;
			ClientToScreen(hWnd, &pt1);
			ClientToScreen(hWnd, &pt2);
			rectClient.left   = pt1.x;
			rectClient.top    = pt1.y;
			rectClient.right  = pt2.x;
			rectClient.bottom = pt2.y;
		
			hBitmap = CopyScreenToBitmap(&rectClient);
			break;
		}
	default:
		return NULL;
	}
	return hBitmap;
}
/*******************************************************
copy the specified part of the window client to a
device-dependent bitmap.
parameter:           HWND, LPRECT
return:              HDIB
*******************************************************/
HBITMAP CopyClientRectToBitmap(HWND hWnd, LPRECT lpRect)
{
	HBITMAP hBitmap = NULL;
	
	if(!hWnd)
		return NULL;
	POINT pt1,pt2;	

	pt1.x = lpRect->left;
	pt1.y = lpRect->top;
	pt2.x = lpRect->right;
	pt2.y = lpRect->bottom;
	ClientToScreen(hWnd, &pt1);
	ClientToScreen(hWnd, &pt2);

	lpRect->left	= pt1.x;
	lpRect->top		= pt1.y;
	lpRect->right	= pt2.x;
	lpRect->bottom	= pt2.y;

	hBitmap = CopyScreenToBitmap(lpRect);

	pt1.x = lpRect->left;
	pt1.y = lpRect->top;
	pt2.x = lpRect->right;
	pt2.y = lpRect->bottom;
	ScreenToClient(hWnd, &pt1);
	ScreenToClient(hWnd, &pt2);
	lpRect->left	= pt1.x;
	lpRect->top		= pt1.y;
	lpRect->right	= pt2.x;
	lpRect->bottom	= pt2.y;
	
	return hBitmap;
}
/***************************************************************
copy the specified part of the screen to a DIB
parameter:     LPRECT
return:        HDIB
***************************************************************/
HDIB CopyScreenToDIB(LPRECT lpRect)
{
	HBITMAP		hBitmap;
	HPALETTE	hPalette;
	HDIB		hDib = NULL;
	
	hBitmap = CopyScreenToBitmap(lpRect);
	
	if(!hBitmap)
		return NULL;
	
	hPalette = GetSystemPalette();

	hDib = BitmapToDIB(hBitmap, hPalette);
	
	DeleteObject(hPalette);
	DeleteObject(hBitmap);

	return hDib;
}
/*************************************************************
copy specified window to DIB
parameter:     HWND,WORD(PringArea)
return:        HDIB
*************************************************************/        
HDIB CopyWindowToDIB(HWND hWnd, WORD fPrintArea)
{
	HBITMAP		hBitmap;
	HPALETTE	hPalette;
	HDIB		hDib = NULL;
	
	hBitmap = CopyWindowToBitmap(hWnd, fPrintArea);
	if(!hBitmap)
		return NULL;
	hPalette = GetSystemPalette();
	hDib = BitmapToDIB(hBitmap, hPalette);

	DeleteObject(hPalette);
	DeleteObject(hBitmap);

	return hDib;
}
/**************************************************************
copy specified area of specified window to DIB
parameter:     HWND, LPRECT
return:        HDIB
**************************************************************/     
HDIB CopyClientRectToDIB(HWND hWnd, LPRECT lpRect)
{
	HBITMAP		hBitmap;
	HPALETTE	hPalette;
	HDIB		hDib = NULL;
	
	hBitmap = CopyClientRectToBitmap(hWnd, lpRect);
	if(!hBitmap)
		return NULL;
	hPalette = GetSystemPalette();
	hDib = BitmapToDIB(hBitmap, hPalette);

	DeleteObject(hPalette);
	DeleteObject(hBitmap);

	return hDib;

}

///////////////////////////////////////////////////////////////

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?