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

📄 dib.cpp

📁 Visual C++_ 600 编程学习捷径
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// Dib.cpp: implementation of the CDib class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "ImageTest.h"
#include "Dib.h"

#include <io.h>
#include <errno.h>

#include <math.h>
#include <direct.h>

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

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

CDib::CDib()
{
	m_hDib = NULL;
	m_bIsImageMap = FALSE;
	m_x1 = m_y1 = 0.0;
	m_x2 = m_y2 = 0.0;
	m_dScale = 0.0;
}

CDib::~CDib()
{
	if(m_hDib != NULL)
	{
		// 释放内存
		::GlobalFree((HGLOBAL) m_hDib);
		m_hDib = NULL;
	}
	//删除调色板对象
	if(m_Pal.GetSafeHandle())
	{
		m_Pal.DeleteObject();
	}
}


/*
 * Dib文件头标志(字符串"BM",写DIB时用到该常数)
 */
#define DIB_HEADER_MARKER   ((WORD) ('M' << 8) | 'B')

/*************************************************************************
 *
 * 函数名称:
 *   PaintDIB()
 *
 * 参数:
 *   HDC hDC            - 输出设备DC
 *   LPRECT lpDCRect    - 绘制矩形区域
 *   LPRECT lpDIBRect   - 要输出的DIB区域
 *
 * 返回值:
 *   BOOL               - 绘制成功返回TRUE,否则返回FALSE。
 *
 * 说明:
 *   该函数主要用来绘制DIB对象。其中调用了StretchDIBits()或者
 * SetDIBitsToDevice()来绘制DIB对象。输出的设备由由参数hDC指
 * 定;绘制的矩形区域由参数lpDCRect指定;输出DIB的区域由参数
 * lpDIBRect指定。
 *
 ************************************************************************/

BOOL CDib::PaintDIB(HDC     hDC,
					LPRECT  lpDCRect,
					LPRECT  lpDIBRect)
{
	LPTSTR    lpDIBHdr;            // BITMAPINFOHEADER指针
	LPTSTR    lpDIBBits;           // DIB象素指针
	BOOL     bSuccess=FALSE;      // 成功标志
	HPALETTE hPal=NULL;           // DIB调色板
	HPALETTE hOldPal=NULL;        // 以前的调色板

	// 判断DIB对象是否为空
	if (m_hDib == NULL)
	{
		// 返回
		return FALSE;
	}

	// 锁定DIB
	lpDIBHdr  = (LPTSTR) ::GlobalLock((HGLOBAL) m_hDib);

	// 找到DIB图像象素起始位置
	lpDIBBits = FindDIBBits(lpDIBHdr);

	// 获取DIB调色板,并选中它
	if (m_Pal.m_hObject != NULL)
	{
		hPal = (HPALETTE) m_Pal.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) m_hDib);
	
	// 恢复以前的调色板
	if (hOldPal != NULL)
	{
		::SelectPalette(hDC, hOldPal, TRUE);
	}
	
	// 返回
	return bSuccess;
}

/*************************************************************************
 *
 * 函数名称:
 *   CreateDIBPalette()
 *
 * 返回值:
 *   BOOL               - 创建成功返回TRUE,否则返回FALSE。
 *
 * 说明:
 *   该函数按照DIB创建一个逻辑调色板,从DIB中读取颜色表并存到调色板中,
 * 最后按照该逻辑调色板创建一个新的调色板。这样
 * 可以用最好的颜色来显示DIB图像。
 *
 ************************************************************************/


BOOL CDib::CreateDIBPalette(HDIB hDIB)
{
	// 指向逻辑调色板的指针
	LPLOGPALETTE lpPal;
	
	// 逻辑调色板的句柄
	HANDLE hLogPal;
	
	// 调色板的句柄
	HPALETTE hPal = NULL;
	
	// 循环变量
	int i;
	
	// 颜色表中的颜色数目
	WORD wNumColors;
	
	// 指向DIB的指针
	LPTSTR lpbi;
	
	// 指向BITMAPINFO结构的指针(Win3.0)
	LPBITMAPINFO lpbmi;
	
	// 指向BITMAPCOREINFO结构的指针
	LPBITMAPCOREINFO lpbmc;
	
	// 表明是否是Win3.0 DIB的标记
	BOOL bWinStyleDIB;
	
	// 创建结果
	BOOL bResult = TRUE;
	
	// 判断DIB是否为空
	if (hDIB == NULL)
	{
		// 返回FALSE
		return FALSE;
	}
	
	// 锁定DIB
	lpbi = (LPTSTR) ::GlobalLock((HGLOBAL) hDIB);
	
	// 获取指向BITMAPINFO结构的指针(Win3.0)
	lpbmi = (LPBITMAPINFO)lpbi;
	
	// 获取指向BITMAPCOREINFO结构的指针
	lpbmc = (LPBITMAPCOREINFO)lpbi;
	
	// 获取DIB中颜色表中的颜色数目
	wNumColors = DIBNumColors(lpbi);
	
	if (wNumColors != 0)
	{
		// 分配为逻辑调色板内存
		hLogPal = ::GlobalAlloc(GHND, sizeof(LOGPALETTE)
									+ sizeof(PALETTEENTRY)
									* wNumColors);
		
		// 如果内存不足,退出
		if (hLogPal == 0)
		{
			// 解除锁定
			::GlobalUnlock((HGLOBAL) hDIB);
			
			// 返回FALSE
			return FALSE;
		}
		
		lpPal = (LPLOGPALETTE) ::GlobalLock((HGLOBAL) hLogPal);
		
		// 设置版本号
		lpPal->palVersion = PALVERSION;
		
		// 设置颜色数目
		lpPal->palNumEntries = (WORD)wNumColors;
		
		// 判断是否是WIN3.0的DIB
		bWinStyleDIB = IS_WIN30_DIB(lpbi);

		// 读取调色板
		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 = m_Pal.CreatePalette(lpPal);
		
		// 解除锁定
		::GlobalUnlock((HGLOBAL) hLogPal);
		
		// 释放逻辑调色板
		::GlobalFree((HGLOBAL) hLogPal);
	}
	
	// 解除锁定
	::GlobalUnlock((HGLOBAL) hDIB);
	
	// 返回结果
	return bResult;
}

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


LPTSTR CDib::FindDIBBits(LPSTR lpbi)
{
	return (lpbi + *(LPDWORD)lpbi + PaletteSize(lpbi));
}


/*************************************************************************
 *
 * 函数名称:
 *   DIBWidth()
 *
 * 参数:
 *   LPTSTR lpbi         - 指向DIB对象的指针
 *
 * 返回值:
 *   DWORD              - DIB中图像的宽度
 *
 * 说明:
 *   该函数返回DIB中图像的宽度。对于Windows 3.0 DIB,返回BITMAPINFOHEADER
 * 中的biWidth值;对于其它返回BITMAPCOREHEADER中的bcWidth值。
 *
 ************************************************************************/


LONG CDib::DIBWidth(LPTSTR lpDIB)
{
	// 指向BITMAPINFO结构的指针(Win3.0)
	LPBITMAPINFOHEADER lpbmi;
	
	// 指向BITMAPCOREINFO结构的指针
	LPBITMAPCOREHEADER lpbmc;

	// 获取指针
	lpbmi = (LPBITMAPINFOHEADER)lpDIB;
	lpbmc = (LPBITMAPCOREHEADER)lpDIB;

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


/*************************************************************************
 *
 * 函数名称:
 *   DIBHeight()
 *
 * 参数:
 *   LPTSTR lpDIB        - 指向DIB对象的指针
 *
 * 返回值:
 *   DWORD              - DIB中图像的高度
 *
 * 说明:
 *   该函数返回DIB中图像的高度。对于Windows 3.0 DIB,返回BITMAPINFOHEADER
 * 中的biHeight值;对于其它返回BITMAPCOREHEADER中的bcHeight值。
 *
 ************************************************************************/


LONG CDib::DIBHeight(LPTSTR lpDIB)
{
	// 指向BITMAPINFO结构的指针(Win3.0)
	LPBITMAPINFOHEADER lpbmi;
	
	// 指向BITMAPCOREINFO结构的指针
	LPBITMAPCOREHEADER lpbmc;

	// 获取指针
	lpbmi = (LPBITMAPINFOHEADER)lpDIB;
	lpbmc = (LPBITMAPCOREHEADER)lpDIB;

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

long CDib::GetWidth()
{
	if(m_hDib == NULL)
		return 0;

	// 锁定DIB
	LPTSTR lpDIB  = (LPTSTR)::GlobalLock((HGLOBAL)m_hDib);

	//得到DIB宽度
	long dwWidth = DIBWidth(lpDIB);

	// 解除锁定
	::GlobalUnlock((HGLOBAL)m_hDib);

	return dwWidth;
}

long CDib::GetHeight()
{
	if(m_hDib == NULL)
		return 0;

	// 锁定DIB
	LPTSTR lpDIB  = (LPTSTR)::GlobalLock((HGLOBAL)m_hDib);

	//得到DIB高度
	long dwHeight = DIBHeight(lpDIB);

	// 解除锁定
	::GlobalUnlock((HGLOBAL)m_hDib);

	return dwHeight;
}

⌨️ 快捷键说明

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