dibapi.cpp

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

CPP
2,454
字号
		return FALSE;
	}
	
	//填写Bitmap文件头的内容
	bmfHeader.bfType = DIB_HEADER_MARKER;//'BM'
	
	dwDibsize = *(LPDWORD)lpbi+DIBNumColors((LPBYTE)lpbi)*sizeof(RGBQUAD);
	
	if((lpbi->biCompression == BI_RLE8)||(lpbi->biCompression == BI_RLE4))
		dwDibsize += lpbi->biSizeImage;
	else
	{
		DWORD dwBmBitsSize;

		dwBmBitsSize = WIDTHBYTES((lpbi->biWidth)*((DWORD)lpbi->biBitCount))*lpbi->biHeight;
		dwDibsize += dwBmBitsSize;
		lpbi->biSizeImage = dwDibsize;
	}
	
	bmfHeader.bfSize = dwDibsize+sizeof(BITMAPFILEHEADER);
	bmfHeader.bfReserved1 = bmfHeader.bfReserved2=0;
	
	bmfHeader.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER)+lpbi->biSize+DIBNumColors((LPBYTE)lpbi)*sizeof(RGBQUAD);
	
	//将文件头的内容和图像信息写回文件中
	WriteFile(	hFile,
				(LPBYTE)&bmfHeader,
				sizeof(BITMAPFILEHEADER),
				&dwWritten,
				NULL);
	WriteFile(	hFile,
				(LPBYTE)lpbi,
				dwDibsize,
				&dwWritten,
				NULL);

	GlobalUnlock(hDib);
	CloseHandle(hFile);
	
	if(dwWritten == 0)
		return FALSE;
	else 
		return TRUE;
}
/**************************************************
free memory associated with a DIB
parameter:   HDIB
return:      void 
**************************************************/
void DestroyDIB(HDIB hDib)
{
	GlobalFree(hDib);
}
/********************************************************
show a DDB with specified area.
parameter:		HDC,
				LPRECT(show),
				HANDLE(to DIB),
				LPRECT(DIB),
				DWORD(mode)
return:			BOOL
********************************************************/
BOOL PaintBitmap(HDC hDC, LPRECT lpDCRect, HBITMAP hDdb, LPRECT lpDdbRect, HPALETTE hPalette, DWORD dwRop)
{
	HDC			hMemDC;
	HBITMAP		hOldBitmap;
	HPALETTE	hOldPal1 = NULL;
	HPALETTE	hOldPal2 = NULL;
	BOOL		bSuccess = FALSE;

	hMemDC = CreateCompatibleDC(hDC);
	if(!hMemDC)
		return FALSE;
	
	if(hPalette)
	{
		hOldPal1 = SelectPalette(hMemDC,hPalette,TRUE);
		hOldPal2 = SelectPalette(hMemDC,hPalette,TRUE);
		RealizePalette(hDC);
	}
	
	hOldBitmap = (HBITMAP)SelectObject(hDC, hDdb);
	
	SetStretchBltMode(hDC, COLORONCOLOR);	
	
	if((RECTWIDTH(lpDCRect) == RECTWIDTH(lpDdbRect))&&(RECTHEIGHT(lpDCRect)==RECTHEIGHT(lpDdbRect)))
		bSuccess = BitBlt(	hDC,
							lpDCRect->left,
							lpDCRect->top,
							lpDCRect->right-lpDCRect->left,
							lpDCRect->bottom-lpDCRect->top,
							hMemDC,
							lpDdbRect->left,
							lpDdbRect->top,
							dwRop);
	else
		bSuccess = StretchBlt(	hDC,
								lpDCRect->left,
								lpDCRect->top,
								lpDCRect->right-lpDCRect->left,
								lpDCRect->bottom-lpDCRect->top,hMemDC,lpDdbRect->left,
								lpDdbRect->top,
								lpDdbRect->right-lpDdbRect->left,
								lpDdbRect->bottom-lpDdbRect->top,
								dwRop);
	
	SelectObject(hMemDC, hOldBitmap);
	if(hOldPal1)
		SelectPalette(hMemDC, hOldPal1, FALSE);
	if(hOldPal2)
		SelectPalette(hMemDC, hOldPal2, FALSE);

	DeleteDC(hDC);

	return bSuccess;
}
/*****************************************************
create a palette from DIB file.
parameter:   LPBYTE(to DIB)
return:      HPALETTE
call:        WORD DIBNumColors(LPBYTE)
*****************************************************/
HPALETTE CreateDIBPalette(LPBYTE lpbi)
{
	LPLOGPALETTE	lpPal;			//到逻辑调色板的指针
	HANDLE			hLogPal;		//到逻辑调色板的句柄
	HPALETTE		hPal = NULL;	//要返回的调色板句柄
	LPBITMAPINFO	lpbmi;			//到BITMAPINFO结构的指针
	BOOL			bWinStyleDib;	//是否为Windows下的位图格式
	int i, wNumColors;

	//检查到位图的指针是否合法
	if(!lpbi)
		return NULL;
	
	//得到指向BITMAPINFO结构的指针
	lpbmi = (LPBITMAPINFO)lpbi;
	
	//得到位图中的颜色数
	wNumColors = DIBNumColors(lpbi);
	//是否为Windows下的位图格式?
	bWinStyleDib = IS_WIN30_DIB(lpbi);
	
	//颜色数不为0表示需要调色板支持
	if(wNumColors)
	{
		//为逻辑调色板分配内存空间
		hLogPal = GlobalAlloc(GHND, sizeof(LOGPALETTE)+sizeof(PALETTEENTRY)*wNumColors);
		if(!hLogPal)
			return NULL;
		
		lpPal = (LPLOGPALETTE)GlobalLock(hLogPal);
		
		
		//填写逻辑调色板的内容
		lpPal->palVersion = PALVERSION;
		lpPal->palNumEntries = wNumColors;
		
		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
			{
				//在此不考虑非Window标准格式的位图
			}
		}
		
		hPal = CreatePalette(lpPal);
		
		if(!hPal)
		{
			GlobalUnlock(hLogPal);
			GlobalFree(hLogPal);
			return NULL;
		}
		
		GlobalUnlock(hLogPal);
		GlobalFree(hLogPal);
	}
	return hPal;
}
/*****************************************************
create a palette from DIB file.
parameter:   HDIB
return:      HPALETTE
call:        WORD DIBNumColors(LPBYTE)
*****************************************************/
HPALETTE CreateDIBPalette(HDIB hDib)
{
	LPBYTE lpbi;
	lpbi = (LPBYTE)GlobalLock(hDib);
	HPALETTE hPal;
	hPal = CreateDIBPalette(lpbi);
	GlobalUnlock(hDib);
	return hPal;
}
/********************************************************
show a DIB with specified area.
parameter:		HDC hdc				--显示设备上下文
				LPRECT lpDCRect		--显示设备的区域
				HANDLE hDib			--位图句柄
				LPRECT lpDibRect	--位图区域
				HPALETTE hPalette	--调色板
				DWORD dwRop			--显示方式
return:			BOOL
********************************************************/
BOOL PaintDIB(HDC hDC, LPRECT lpDCRect, HDIB hDib, LPRECT lpDibRect, HPALETTE hPalette, DWORD dwRop)
{
	LPBYTE lpDib;			//指向BITMAPINFOHEADER的指针
	LPBYTE lpDibbits;		//指向图象数据的指针
	BOOL bSuccess = FALSE;	
	HPALETTE hOldPal = NULL;//原有调色板句柄

	//检查位图句柄是否合法
	if(!hDib)
		return FALSE;

	//得到指向BITMAPINFOHEADER的指针和指向图象数据的指针
	lpDib = (LPBYTE)GlobalLock(hDib);
	lpDibbits = lpDib+sizeof(BITMAPINFOHEADER)+DIBNumColors(lpDib)*sizeof(RGBQUAD);
	
	//如果没有提供调色板,则从位图细心中创建一个调色板
	if(!hPalette)
		hPalette = CreateDIBPalette(lpDib);
	
	//在绘图上下文中采用新的调色板
	if(hPalette)
	{
		hOldPal = SelectPalette(hDC, hPalette, TRUE);
		RealizePalette(hDC);
	}
	
	//调用函数设置绘图方式并绘图
	SetStretchBltMode(hDC, COLORONCOLOR);
	bSuccess = StretchDIBits(	hDC,
								lpDCRect->left,
								lpDCRect->top,
								RECTWIDTH(lpDCRect),
								RECTHEIGHT(lpDCRect),
								lpDCRect->left,
								((LPBITMAPINFOHEADER)lpDib)->biHeight-lpDibRect->top-RECTHEIGHT(lpDibRect),
								RECTWIDTH(lpDibRect),
								RECTHEIGHT(lpDibRect),
								lpDibbits,
								(LPBITMAPINFO)lpDib,
								DIB_RGB_COLORS,
								SRCCOPY);
	
	//清除工作
	GlobalUnlock(hDib);
	
	if(hOldPal)
		SelectPalette(hDC, hOldPal, FALSE);
	
	return bSuccess;
}
/********************************************************
show a DIB fully.
parameter:  CDC*,
			LPCSTR(to file)
return:     BOOL
********************************************************/
BOOL DisplayDIB(CDC* pDC, LPCSTR lpszBitmap)
{
	LPBITMAPINFO	lpDib;
	LPSTR			lpBits;
	CPalette		*pPal, *pOldPal;

	lpDib = (LPBITMAPINFO)LoadDIBFromResource(lpszBitmap);
	if(lpDib == NULL)
		return FALSE;
	lpBits = (LPSTR)lpDib+sizeof(BITMAPINFOHEADER)+DIBNumColors((LPSTR)lpDib)*sizeof(RGBQUAD);
	pPal = (CPalette*)CreateDIBPalette((LPBYTE)lpDib);
	pOldPal = pDC->SelectPalette(pPal,TRUE);
	pDC->RealizePalette();

	SetDIBitsToDevice(	pDC->GetSafeHdc(),
						0,
						0,
						(int)lpDib->bmiHeader.biWidth,
						(int)lpDib->bmiHeader.biHeight,
						0,
						0,
						0,
						(UINT)lpDib->bmiHeader.biHeight,
						lpBits,
						lpDib,
						DIB_RGB_COLORS);

	pDC->SelectPalette(pOldPal, FALSE);
	return TRUE;
}
/**************************************************
Create DIBSection from DIB.
parameter:      LPBYTE(lpDIB)
return:         HBITMAP
**************************************************/
HBITMAP DIBToDIBSection(LPBYTE lpDib)
{
	LPBYTE	lpSourceBits;
	HDC		hDC = NULL, hSourceDC;
	HBITMAP hSourceBitmap, hOldSourceBitmap;
	DWORD	dwSourceBitsSize;

	LPBITMAPINFO lpSrcDib = (LPBITMAPINFO)lpDib;

	if(!lpSrcDib)
		return NULL;
	
	hDC = GetDC(NULL);
	hSourceBitmap = CreateDIBSection(	hDC,
										lpSrcDib,
										DIB_RGB_COLORS,
										(VOID**)&lpSourceBits,
										NULL,
										0);
	hSourceDC = CreateCompatibleDC(hDC);
	
	dwSourceBitsSize = lpSrcDib->bmiHeader.biHeight
						*BytesPerLine((LPBYTE)&(lpSrcDib->bmiHeader));
	memcpy(	lpSourceBits, 
			FindDIBBits((LPBYTE)lpSrcDib), 
			dwSourceBitsSize);
	
	hOldSourceBitmap = (HBITMAP)SelectObject(hSourceDC, hSourceBitmap);
	
	if(lpSrcDib->bmiHeader.biBitCount <= 8)
		SetDIBColorTable(	hSourceDC,
							0,
							1<<lpSrcDib->bmiHeader.biBitCount,
							lpSrcDib->bmiColors);
	
	SelectObject(hSourceDC, hOldSourceBitmap);
	DeleteDC(hSourceDC);
	ReleaseDC(NULL,hDC);
	
	GdiFlush();

	return hSourceBitmap;
}
/**************************************************
Create DIBSection from DIB.
parameter:      HDIB
return:         HBITMAP
**************************************************/
HBITMAP DIBToDIBSection(HDIB hDib)
{
	LPBYTE lpDib;
	HBITMAP hBitmap;
	lpDib = (LPBYTE)GlobalLock(hDib);
	hBitmap = DIBToDIBSection(lpDib);
	GlobalUnlock(hDib);
	return hBitmap;
}
/**************************************************
create DIB to DIBSection
parameter:      HBITMAP
return:         HDIB
**************************************************/
HDIB DIBSectionToDIB(HBITMAP hBitmap)
{
	HDC				hDC = NULL, hSourceDC;
	HBITMAP			hOldSourceBitmap;
	HDIB			hNewDib;
	LPBITMAPINFO	lpbmi = NULL;
	DWORD			dwSize;
	DIBSECTION		ds;
	DWORD			dwColorNum;

	GetObject(hBitmap, sizeof(DIBSECTION), &ds);
	dwColorNum = ds.dsBmih.biClrUsed;
	if(dwColorNum == 0 && ds.dsBmih.biBitCount <= 8)
		dwColorNum = 1<<ds.dsBmih.biBitCount;
	
	dwSize = sizeof(BITMAPINFOHEADER)+(dwColorNum*sizeof(RGBQUAD))+ds.dsBmih.biSizeImage;
	hNewDib = GlobalAlloc(GHND, dwSize);
	if(!hNewDib)
		return NULL;
	lpbmi = (LPBITMAPINFO)GlobalLock(hNewDib);
	if(!lpbmi)
		return NULL;
	lpbmi->bmiHeader.biSize			 = sizeof(BITMAPINFOHEADER);
	lpbmi->bmiHeader.biWidth		 = ds.dsBm.bmWidth;
	lpbmi->bmiHeader.biHeight		 = ds.dsBm.bmHeight;
	lpbmi->bmiHeader.biPlanes		 = 1;
	lpbmi->bmiHeader.biBitCount		 = ds.dsBmih.biBitCount;
	lpbmi->bmiHeader.biCompression	 = ds.dsBmih.biCompression;
	lpbmi->bmiHeader.biSizeImage	 = ds.dsBmih.biSizeImage;
	lpbmi->bmiHeader.biXPelsPerMeter = ds.dsBmih.biXPelsPerMeter;
	lpbmi->bmiHeader.biYPelsPerMeter = ds.dsBmih.biYPelsPerMeter;
	lpbmi->bmiHeader.biClrUsed		 = ds.dsBmih.biClrUsed;
	lpbmi->bmiHeader.biClrImportant  = ds.dsBmih.biClrImportant;
	
	hDC = GetDC(NULL);
	
	if(!GetDIBits(	hDC, 
					hBitmap, 
					0L, 
					(DWORD)ds.dsBm.bmHeight,
					(LPBYTE)lpbmi+(WORD)lpbmi->bmiHeader.biSize+(dwColorNum*sizeof(RGBQUAD)),
					(LPBITMAPINFO)lpbmi,
					(DWORD)DIB_RGB_COLORS))
	{
		GlobalUnlock(hNewDib);
		ReleaseDC(NULL, hDC);
		return NULL;
	}
	
	hSourceDC = CreateCompatibleDC(hDC);
	
	hOldSourceBitmap = (HBITMAP)SelectObject(hSourceDC, hBitmap);
	
	if(lpbmi->bmiHeader.biBitCount <= 8)
		GetDIBColorTable(	hSourceDC,
							0,
							1<<lpbmi->bmiHeader.biBitCount,
							lpbmi->bmiColors);
	
	SelectObject(hSourceDC, hOldSourceBitmap);
	DeleteDC(hSourceDC);
	ReleaseDC(NULL, hDC);
	GlobalUnlock(hNewDib);

	return hNewDib;
}
/***********************************************************
Copy the color table from one CF_DIB to another.
parameter:      LPBITMAPINFO(target),
				LPBITMAPINFO(source),
                HPALETTE
return:         BOOL
***********************************************************/
BOOL CopyColorTable(LPBITMAPINFO lpTarget, LPBITMAPINFO lpSource, HPALETTE hPalSrc)
{
	switch(lpTarget->bmiHeader.biBitCount)
	{
	case 8:
		{
		if(hPalSrc)
		{
			PALETTEENTRY pe[256];
			UINT i;

			GetPaletteEntries(hPalSrc, 0, 256, pe);
			for(i=0;i<256;i++)
			{
				lpTarget->bmiColors[i].rgbRed		= pe[i].peRed;
				lpTarget->bmiColors[i].rgbGreen		= pe[i].peGreen;
				lpTarget->bmiColors[i].rgbBlue		= pe[i].peBlue;
				lpTarget->bmiColors[i].rgbReserved	= 0;
			}
		}
		else
		{
			if(lpSource->bmiHeader.biBitCount == 8)
			{
				memcpy(lpTarget->bmiColors, lpSource->bmiColors, 256*sizeof(RGBQUAD));
			}
			else
			{
				MessageBox(NULL, "error no match color table", "error", MB_OK);
				return FALSE;
			}
		}
		break;
		}
	case 4:
		{
		if(hPalSrc)
		{
			PALETTEENTRY pe[16];
			UINT i;

			GetPaletteEntries(hPalSrc, 0, 256, pe);
			for(i=0;i<16;i++)
			{
				lpTarget->bmiColors[i].rgbRed		= pe[i].peRed;
				lpTarget->bmiColors[i].rgbGreen		= pe[i].peGreen;
				lpTarget->bmiColors[i].rgbBlue		= pe[i].peBlue;
				lpTarget->bmiColors[i].rgbReserved	= 0;
			}
		}
		else
		{
			if(lpSource->bmiHeader.biBitCount == 4)

⌨️ 快捷键说明

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