⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dibimage.cpp

📁 含《Visual c++数字图像处理典型算法及实现》这本书里所有源代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
///////////////////////////////////////////////////////////////////////
// DibImage.cpp: implementation of the CDibImage class.
//  DIB(Independent Bitmap) 函数:
//
//  PaintDIB()          - 绘制DIB对象
//  CreateDIBPalette()  - 创建DIB对象调色板
//  FindDIBBits()       - 返回DIB图像象素起始位置
//  DIBWidth()          - 返回DIB宽度
//  DIBHeight()         - 返回DIB高度
//  PaletteSize()       - 返回DIB调色板大小
//  DIBNumColors()      - 计算DIB调色板颜色数目
//  CopyHandle()        - 拷贝内存块
//
//  SaveDIB()           - 将DIB保存到指定文件中
//  ReadDIBFile()       - 重指定文件中读取DIB对象
//
//  图像点运算函数:
//
//  LinerTrans()		- 图像线性变换
//	WindowTrans()		- 图像窗口变换
//  GrayStretch()		- 图像灰度拉伸
//  InteEqualize()		-直方图均衡
//
//	图像几何变换函数
//  TranslationDIB1()   - 图像平移
//  TranslationDIB()    - 图像平移
//  MirrorDIB()		    - 图像镜像
//  TransposeDIB()		- 图像转置
//  ZoomDIB()			- 图像缩放
//  RotateDIB()			- 图像旋转
//	
//  图像正交变换函数:
//
//  FFT()				- 快速付立叶变换
//  IFFT()				- 快速付立叶反变换
//  DCT()				- 离散余弦变换
//  WALSH()				- 沃尔什-哈达玛变换
//
//  Fourier()			- 图像的付立叶变换
//  DIBDct()			- 图像的离散余弦变换
//  DIBWalsh()			- 图像的沃尔什-哈达玛变换
//
//	图像模板变换函数
//
//  Template()			- 图像模板变换,通过改变模板,可以用它实现
//						  图像的平滑、锐化、边缘识别等操作。
//  MedianFilter()		- 图像中值滤波。
//  GetMedianNum()		- 获取中值。被函数MedianFilter()调用来求中值。
//  ReplaceColorPal()	- 更换伪彩色编码表。
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "Direct.h"
#include "DibImage.h"

#include <math.h>

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CDibImage::CDibImage()
{

}

CDibImage::~CDibImage()
{

}

//////////////////////////////////////////////////////////////////////
// DIB(Independent Bitmap) 函数
//////////////////////////////////////////////////////////////////////

/*************************************************************************
 * 函数名称:
 *   PaintDIB()
 * 参数:
 *   HDC hDC            - 输出设备DC
 *   LPRECT lpDCRect    - 绘制矩形区域
 *   HDIB hDIB          - 指向DIB对象的指针
 *   LPRECT lpDIBRect   - 要输出的DIB区域
 *   CPalette* pPal     - 指向DIB对象调色板的指针
 * 返回值:
 *   BOOL               - 绘制成功返回TRUE,否则返回FALSE。
 * 说明:
 *   该函数主要用来绘制DIB对象。其中调用了StretchDIBits()或者
 * SetDIBitsToDevice()来绘制DIB对象。输出的设备由由参数hDC指
 * 定;绘制的矩形区域由参数lpDCRect指定;输出DIB的区域由参数
 * lpDIBRect指定。
 ************************************************************************/
BOOL CDibImage::PaintDIB(HDC     hDC,
					LPRECT  lpDCRect,
					HDIB    hDIB,
					LPRECT  lpDIBRect,
					CPalette* pPal)
{
	LPSTR    lpDIBHdr;            // BITMAPINFOHEADER指针
	LPSTR    lpDIBBits;           // DIB象素指针
	BOOL     bSuccess=FALSE;      // 成功标志
	HPALETTE hPal=NULL;           // DIB调色板
	HPALETTE hOldPal=NULL;        // 以前的调色板

	if (hDIB == NULL)
	{
		return FALSE;
	}
	
	lpDIBHdr  = (LPSTR)::GlobalLock((HGLOBAL) hDIB);// 锁定DIB	
	lpDIBBits = FindDIBBits(lpDIBHdr);	// 找到DIB图像象素起始位置

	if (pPal != NULL)					// 获取DIB调色板,并选中它
	{
		hPal = (HPALETTE) pPal->m_hObject;	
		hOldPal = ::SelectPalette(hDC, hPal, TRUE);	// 选中调色板
	}

	::SetStretchBltMode(hDC, COLORONCOLOR);			// 设置显示模式

	// 判断是调用StretchDIBits()还是SetDIBitsToDevice()来绘制DIB对象
	if ((RECTWIDTH(lpDCRect)  == RECTWIDTH(lpDIBRect)) &&
	   (RECTHEIGHT(lpDCRect) == RECTHEIGHT(lpDIBRect)))
	{
		// 原始大小,不用拉伸。
		bSuccess = ::SetDIBitsToDevice(hDC,                    // hDC
								   lpDCRect->left,             // DestX
								   lpDCRect->top,              // DestY
								   RECTWIDTH(lpDCRect),        // nDestWidth
								   RECTHEIGHT(lpDCRect),       // nDestHeight
								   lpDIBRect->left,            // SrcX
								   (int)DIBHeight(lpDIBHdr) -
									  lpDIBRect->top -
									  RECTHEIGHT(lpDIBRect),   // SrcY
								   0,                          // nStartScan
								   (WORD)DIBHeight(lpDIBHdr),  // nNumScans
								   lpDIBBits,                  // lpBits
								   (LPBITMAPINFO)lpDIBHdr,     // lpBitsInfo
								   DIB_RGB_COLORS);            // wUsage
	}
    else
	{
		// 非原始大小,拉伸。
		bSuccess = ::StretchDIBits(hDC,                          // hDC
							   lpDCRect->left,                 // DestX
							   lpDCRect->top,                  // DestY
							   RECTWIDTH(lpDCRect),            // nDestWidth
							   RECTHEIGHT(lpDCRect),           // nDestHeight
							   lpDIBRect->left,                // SrcX
							   lpDIBRect->top,                 // SrcY
							   RECTWIDTH(lpDIBRect),           // wSrcWidth
							   RECTHEIGHT(lpDIBRect),          // wSrcHeight
							   lpDIBBits,                      // lpBits
							   (LPBITMAPINFO)lpDIBHdr,         // lpBitsInfo
							   DIB_RGB_COLORS,                 // wUsage
							   SRCCOPY);                       // dwROP
	}
	 
	::GlobalUnlock((HGLOBAL) hDIB);				// 解除锁定	
	if (hOldPal != NULL)
	{
		::SelectPalette(hDC, hOldPal, TRUE);	// 恢复以前的调色板
	}	
	return bSuccess;
}

/*************************************************************************
 * 函数名称:
 *   CreateDIBPalette()
 * 参数:
 *   HDIB hDIB          - 指向DIB对象的指针
 *   CPalette* pPal     - 指向DIB对象调色板的指针
 * 返回值:
 *   BOOL               - 创建成功返回TRUE,否则返回FALSE。
 * 说明:
 *   该函数按照DIB创建一个逻辑调色板,从DIB中读取颜色表并存到调色板中,
 * 最后按照该逻辑调色板创建一个新的调色板,并返回该调色板的句柄。这样
 * 可以用最好的颜色来显示DIB图像。
 ************************************************************************/
BOOL CDibImage::CreateDIBPalette(HDIB hDIB, CPalette* pPal)
{
	
	LPLOGPALETTE lpPal;		// 指向逻辑调色板的指针
	HANDLE hLogPal;			// 逻辑调色板的句柄
	HPALETTE hPal = NULL;	// 调色板的句柄
	int i;					// 循环变量	
	WORD wNumColors;		// 颜色表中的颜色数目	
	LPSTR lpbi;				// 指向DIB的指针	
	LPBITMAPINFO lpbmi;		// 指向BITMAPINFO结构的指针(Win3.0)	
	LPBITMAPCOREINFO lpbmc;	// 指向BITMAPCOREINFO结构的指针	
	BOOL bWinStyleDIB;		// 表明是否是Win3.0 DIB的标记	
	BOOL bResult = FALSE;	// 创建结果
	
	if (hDIB == NULL)
	{
		return FALSE;
	}
		
	lpbi = (LPSTR) ::GlobalLock((HGLOBAL) hDIB);	// 锁定DIB
	lpbmi = (LPBITMAPINFO)lpbi;		// 获取指向BITMAPINFO结构的指针(Win3.0)
	lpbmc = (LPBITMAPCOREINFO)lpbi;	// 获取指向BITMAPCOREINFO结构的指针
	wNumColors = DIBNumColors(lpbi);// 获取DIB中颜色表中的颜色数目
	
	if (wNumColors != 0)
	{
		// 分配为逻辑调色板内存
		hLogPal = ::GlobalAlloc(GHND, sizeof(LOGPALETTE)
									+ sizeof(PALETTEENTRY)
									* wNumColors);	
		// 如果内存不足,退出
		if (hLogPal == 0)
		{	
			::GlobalUnlock((HGLOBAL) hDIB);	// 解除锁定
			return FALSE;
		}
		
		lpPal = (LPLOGPALETTE) ::GlobalLock((HGLOBAL) hLogPal);		
		lpPal->palVersion = PALVERSION;			// 设置版本号
		lpPal->palNumEntries = (WORD)wNumColors;// 设置颜色数目
		bWinStyleDIB = IS_WIN30_DIB(lpbi);		// 判断是否是WIN3.0的DIB

		// 读取调色板
		for (i = 0; i < (int)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;
			}
		}
			
		bResult = pPal->CreatePalette(lpPal);// 按照逻辑调色板创建调色板,并返回指针
		::GlobalUnlock((HGLOBAL) hLogPal);	// 解除锁定
		::GlobalFree((HGLOBAL) hLogPal);	// 释放逻辑调色板
	}
	
	::GlobalUnlock((HGLOBAL) hDIB);			// 解除锁定
	return bResult;
}

/*************************************************************************
 * 函数名称:
 *   FindDIBBits()
 * 参数:
 *   LPSTR lpbi         - 指向DIB对象的指针
 * 返回值:
 *   LPSTR              - 指向DIB图像象素起始位置
 * 说明:
 *   该函数计算DIB中图像象素的起始位置,并返回指向它的指针。
 ************************************************************************/
LPSTR CDibImage::FindDIBBits(LPSTR lpbi)
{
	return (lpbi + *(LPDWORD)lpbi + PaletteSize(lpbi));
}

/*************************************************************************
 * 函数名称:
 *   DIBWidth()
 * 参数:
 *   LPSTR lpbi         - 指向DIB对象的指针
 * 返回值:
 *   DWORD              - DIB中图像的宽度
 * 说明:
 *   该函数返回DIB中图像的宽度。对于Windows 3.0 DIB,返回BITMAPINFOHEADER
 * 中的biWidth值;对于其它返回BITMAPCOREHEADER中的bcWidth值。
 ************************************************************************/
DWORD CDibImage::DIBWidth(LPSTR lpDIB)
{
	LPBITMAPINFOHEADER lpbmi;	// 指向BITMAPINFO结构的指针(Win3.0)
	LPBITMAPCOREHEADER lpbmc;	// 指向BITMAPCOREINFO结构的指针
	lpbmi = (LPBITMAPINFOHEADER)lpDIB;
	lpbmc = (LPBITMAPCOREHEADER)lpDIB;

	// 返回DIB中图像的宽度
	if (IS_WIN30_DIB(lpDIB))
	{		
		return lpbmi->biWidth;		// 对于Windows 3.0 DIB,返回lpbmi->biWidth
	}
	else
	{		
		return (DWORD)lpbmc->bcWidth;	// 对于其它格式的DIB,返回lpbmc->bcWidth
	}
}

/*************************************************************************
 * 函数名称:
 *   DIBHeight()
 * 参数:
 *   LPSTR lpDIB        - 指向DIB对象的指针
 * 返回值:
 *   DWORD              - DIB中图像的高度
 * 说明:
 *   该函数返回DIB中图像的高度。对于Windows 3.0 DIB,返回BITMAPINFOHEADER
 * 中的biHeight值;对于其它返回BITMAPCOREHEADER中的bcHeight值。
 ************************************************************************/
DWORD CDibImage::DIBHeight(LPSTR lpDIB)
{	
	LPBITMAPINFOHEADER lpbmi;	// 指向BITMAPINFO结构的指针(Win3.0)
	LPBITMAPCOREHEADER lpbmc;	// 指向BITMAPCOREINFO结构的指针
	lpbmi = (LPBITMAPINFOHEADER)lpDIB;
	lpbmc = (LPBITMAPCOREHEADER)lpDIB;

	// 返回DIB中图像的宽度
	if (IS_WIN30_DIB(lpDIB))
	{		
		return lpbmi->biHeight;		// 对于Windows 3.0 DIB,返回lpbmi->biHeight
	}
	else
	{		
		return (DWORD)lpbmc->bcHeight;	// 对于其它格式的DIB,返回lpbmc->bcHeight
	}
}

/*************************************************************************
 * 函数名称:
 *   PaletteSize()
 * 参数:
 *   LPSTR lpbi         - 指向DIB对象的指针
 * 返回值:
 *   WORD               - DIB中调色板的大小
 * 说明:
 *   该函数返回DIB中调色板的大小。对于Windows 3.0 DIB,返回颜色数目×
 * RGBQUAD的大小;对于其它返回颜色数目×RGBTRIPLE的大小。
 ************************************************************************/
WORD CDibImage::PaletteSize(LPSTR lpbi)
{
	// 计算DIB中调色板的大小
	if (IS_WIN30_DIB (lpbi))
	{
		//返回颜色数目×RGBQUAD的大小
		return (WORD)(DIBNumColors(lpbi) * sizeof(RGBQUAD));
	}
	else
	{
		//返回颜色数目×RGBTRIPLE的大小
		return (WORD)(DIBNumColors(lpbi) * sizeof(RGBTRIPLE));
	}
}

/*************************************************************************
 * 函数名称:
 *   DIBNumColors()
 * 参数:
 *   LPSTR lpbi         - 指向DIB对象的指针
 * 返回值:
 *   WORD               - 返回调色板中颜色的种数
 * 说明:
 *   该函数返回DIB中调色板的颜色的种数。对于单色位图,返回2,
 * 对于16色位图,返回16,对于256色位图,返回256;对于真彩色
 * 位图(24位),没有调色板,返回0。
 ************************************************************************/
WORD CDibImage::DIBNumColors(LPSTR lpbi)
{
	WORD wBitCount;

	// 对于Windows的DIB, 实际颜色的数目可以比象素的位数要少。
	// 对于这种情况,则返回一个近似的数值。
	
	// 判断是否是WIN3.0 DIB
	if (IS_WIN30_DIB(lpbi))
	{
		DWORD dwClrUsed;
		dwClrUsed = ((LPBITMAPINFOHEADER)lpbi)->biClrUsed;	// 读取dwClrUsed值
		
		if (dwClrUsed != 0)
		{
			// 如果dwClrUsed(实际用到的颜色数)不为0,直接返回该值
			return (WORD)dwClrUsed;
		}
	}

	// 读取象素的位数
	if (IS_WIN30_DIB(lpbi))
	{		
		wBitCount = ((LPBITMAPINFOHEADER)lpbi)->biBitCount;	// 读取biBitCount值
	}
	else
	{		
		wBitCount = ((LPBITMAPCOREHEADER)lpbi)->bcBitCount;	// 读取biBitCount值
	}
	

⌨️ 快捷键说明

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