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

📄 dibapi.cpp

📁 利用混沌算法,进行迭代加密数字图象,Logistic映射原理.
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//***********************************************
//文件名:dibapi.cpp
//
//DIB(Independent Bitmap) API函数库;
//
//PaintDIB()            - 绘制DIB对象
//CreateDIBPalette()    - 创建DIB对象调色板
//FindDIBBits()         - 返回DIB图象象素起始位置
//DIBWidth()            - 返回DIB宽度
//DIBHeight()           - 返回DIB高度
//PaletteSize()         - 返回DIB调色板大小
//DIBNumColors()        - 计算DIB调色板颜色数目
//CopyHandle()          - 拷贝内存块
//
//SaveDIB()             -将DIB保存到指定文件中
//ReadDIBFile()         - 重指定文件中读取DIB的对象
//
//**************************************************
#include "stdafx.h"
#include "dibapi.h"
#include <io.h>
#include <errno.h>

#include <math.h>
#include <direct.h>
/*
*DIB文件头标志(字符串"BM",写DIB是用到该常数)
*/
#define DIB_HEADER_MARKER  ((WORD)('M'<<8)|'B')
#define PI 3.1415926535
/************************************************************
*
*函数名称:
*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 WINAPI 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; //以前的调色板

	//判断DIB对象是否为空
	if(hDIB == NULL)
	{
		//返回
		return FALSE;
	}
	//锁定DIB
	lpDIBHdr = (LPSTR)::GlobalLock((HGLOBAL) hDIB);

	//找到DIB图象象素起始位置
	lpDIBBits= ::FindDIBBits(lpDIBHdr);
	
	//获取DIB调色板,并选中它
	if(pPal!=NULL)
	{
		hPal = (HPALETTE)pPal->m_hObject;
		//选中调色板
		hOldPal = ::SelectPalette(hDC,hPal,TRUE);
	}

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

	//判断是调用StretchDIBits()还是SetBitsToDevice()来绘制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 WINAPI CreateDIBPalette(HDIB hDIB,CPalette* pPal)
{
	//指向逻辑调色板的指针
	LPLOGPALETTE lpPal;

	//逻辑调色板的句柄
	HANDLE hLogPal;

	//调色板的句柄
	HPALETTE hPal=NULL;

	//循环变量
	int i;

	//颜色表中的颜色树目
	WORD wNumColors;

	//指向DIB的指针
	LPSTR lpbi;

	//指向BITMAPINFO结构的指针(Win3.0)
	LPBITMAPINFO lpbmi;

	//指向BITMAPCOREINFO结构的指针
	LPBITMAPCOREINFO lpbmc;

	//表明是否是Win3.0的标记
	BOOL bWinStyleDIB;

	//创建结果
	BOOL bResult =FALSE;

	//判断DIB是否为空
	if(hDIB == NULL)
	{
		//返回FALSE;
		return FALSE;
	}
	//锁定DIB
	lpbi = (LPSTR)::GlobalLock((HGLOBAL)hDIB);

	//获取指向BITMAPINFO结构的指针
	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 = pPal->CreatePalette(lpPal);

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

		//释放逻辑调色板
		::GlobalFree((HGLOBAL)hLogPal);
	}
	//解除锁定
	::GlobalUnlock((HGLOBAL)hDIB);
	
	//返回结果
	return bResult;
	}
/************************************************************
*
*函数名称:
*      FindDIBBits()
*
*参数:
*   LPSTR lpbi   -指向DIB对象的指针
*
* 返回值:
*  LPSTR           -指向DIB图象象素起始位置
*
*说明:
*    该函数计算DIB中图象象素的起始位置,并返回指向它的指针
*
***************************************************************/

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

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

DWORD WINAPI DIBWidth(LPSTR lpDIB)
{
	//指向BITMAPINFO结构的指针(Windows 3.0)
	LPBITMAPINFOHEADER lpbmi;

	//指向BITMAPCOREINFO结构的指针
	LPBITMAPCOREHEADER lpbmc;

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

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

/************************************************************
*
*函数名称:
*      DIBHeight()
*
*参数:
*   LPSTR lpbi   -指向DIB对象的指针
*
* 返回值:
*  DWORD     -DIB中图象的高度
*
*说明:
*    该函数返回DIB中图象的高度,对于Windows 3.0 DIB,返回
*BITMAPINFOHEADER中的biHeight值,对于其他返回BITMAPCOREINFO
*的bcHeight值。
*
***************************************************************/
DWORD WINAPI DIBHeight(LPSTR lpDIB)
{
	//指向BITMAPINFO结构的指针(Windows 3.0)
	LPBITMAPINFOHEADER lpbmi;

	//指向BITMAPCOREINFO结构的指针
	LPBITMAPCOREHEADER lpbmc;

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

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

}

/************************************************************
*
*函数名称:
*      PaletteSize()
*
*参数:
*   LPSTR lpbi   -指向DIB对象的指针
*
* 返回值:
*  WORD     -DIB中调色板的大小
*
*说明:
*    该函数返回DIB中调色板的大小。对于Window 3.0 DIB ,返回
* 颜色数目*RGBQUAD的大小;对于其他返回颜色数目*RGBTRIPLED的大小。
*   
*
***************************************************************/
WORD WINAPI 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 WINAPI DIBNumColors(LPSTR lpbi)
{
	WORD wBitCount;

	//对于Windows的DIB,实际颜色的数目可以比象素的位数要少
	//对于这种情况,则返回一个近似的数值

	//判断是否是WIN3。0 DIB
	if(IS_WIN30_DIB(lpbi))
	{
		DWORD dwClrUsed;

		//读取dwClrUsed 的值
		dwClrUsed = ((LPBITMAPINFOHEADER)lpbi)->biClrUsed;

		if(dwClrUsed !=0)
		{
			//如果dwClrUsed 不为0,直接返回该值
			return (WORD)dwClrUsed;
		}
	}
	
	//读取象素的位数
	if(IS_WIN30_DIB(lpbi))
	{
		//读取biBitCount值
		wBitCount = ((LPBITMAPINFOHEADER)lpbi)->biBitCount;
	}
	else
	{
		//读取biBitCount值
		wBitCount = ((LPBITMAPCOREHEADER)lpbi)->bcBitCount;
	}
	//按照象素的位数计算颜色数目
	 switch(wBitCount)
	 {
	 case 1:
		 return 2;
	 case 4:
		 return 16;
	 case 8:
		 return 256;
	 default:
		 return 0;
	 }
}

/************************************************************
*
*函数名称:
*      CopyHandle()
*
*参数:
*   HGLOBAL		h  -要复制的内存区域
*
* 返回值:
*  HGLOBAL      -复制后的新内存区域
*
*说明:
*  该函数复制指定的内存区域。返回复制后的新内存区域,出错时返回0。
*   
*
***************************************************************/

HGLOBAL WINAPI CopyHandle(HGLOBAL h)
{
	if(h==NULL)
		return NULL;

	//	获取指定内存区域大小
	DWORD dwLen= ::GlobalSize((HGLOBAL)h);

	//分配新内存空间
	HGLOBAL hCopy = ::GlobalAlloc(GHND,dwLen);

	//判断分配是否成功
	if(hCopy!=NULL)
	{
		//锁定
		void *lpCopy = ::GlobalLock((HGLOBAL)hCopy);
		void *lp =::GlobalLock((HGLOBAL)h);

		//复制
		memcpy(lpCopy,lp,dwLen);

		//解除锁定
		::GlobalUnlock(hCopy);
		::GlobalUnlock(h);
	}

	return hCopy;
}

/************************************************************
*
*函数名称:
*      SaveDIB()
*
*参数:
*   HDIB hDib   - 要保存的DIB
*   CFill &file - 保存文件CFile
* 返回值:
*  BOOL      -成功返回TRUE,否则返回FALSE或则CfileException
*
*说明:
*  该函数将指定的DIB对象保存到指定的CFile中。该CFile由调用程序
*打开和关闭
*   
*
***************************************************************/

BOOL WINAPI SaveDIB(HDIB hDib,CFile& file)
{
	//Bitmap文件头
	BITMAPFILEHEADER bmfHdr;

	//指向BITMAPINFOHEADER的指针
	LPBITMAPINFOHEADER lpBI;

	//DIB大小
	DWORD dwDIBSize;

	if(hDib==NULL)
	{
		//如果DIB为空,返回FALSE
		return FALSE;
	}

	//读取BITMAPINFO结构,并锁定
	lpBI = (LPBITMAPINFOHEADER)::GlobalLock((HGLOBAL)hDib);

	if(lpBI == NULL)
	{
		//为空,返回FALSE
		return FALSE;
	}

	//判断是否是WIN 3.0DIB
	if(!IS_WIN30_DIB(lpBI))
	{
		//不支持其他类型的DIB保存

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

		//返回FALSE
		return FALSE;

⌨️ 快捷键说明

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