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

📄 mbmpclass.cpp

📁 在充分研究了原有的二值图像加密算法的基础上
💻 CPP
字号:
// MBmpClass.cpp: implementation of the MBmpClass class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "FPSystem.h"
#include "MBmpClass.h"

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

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

MBmpClass::MBmpClass()
{
	hImgData=NULL;
	hBitmap=NULL;
    hPalette=NULL;
}

MBmpClass::~MBmpClass()
{
	if(hBitmap)
		DeleteObject(hBitmap);
	if(hPalette)
		DeleteObject(hPalette);
	if(hImgData!=NULL)
	{
		GlobalUnlock(hImgData);
		GlobalFree(hImgData);  
		hImgData=NULL; 
	}
}

/****************************************************************
 *
 * 函数名称:
 *  LoadBMPFile();
 *
 * 参数: 
 *  char *inFileName       加载图像的文件名  
 *  CDC *pDC               设备上下文
 * 返回值:
 *   TRUE                  成功读取;
 *   FALSE                 失败;
 *
 * 说明:
 *    该函数读入图像文件文件数据到全局内存句柄hImgData中;
 *
 ****************************************************************/
BOOL MBmpClass::LoadBmpFile(CString &inFileName,CDC *pDC)   //070426加上了CDC *pDC
{
	if(hImgData!=NULL)
	{
		GlobalUnlock(hImgData);
		GlobalFree(hImgData);  
		hImgData=NULL;
	}

	CFile file;  //文件对象
	if(NULL==file.Open(inFileName,CFile::modeRead))
	{
		AfxMessageBox("文件打开有误!",MB_OK|MB_ICONEXCLAMATION);
		return FALSE;
	}
    //读入文件头,并判断是否为Bmp格式
    file.Read((LPSTR)&bf,sizeof(BITMAPFILEHEADER));
	if(bf.bfType!=0x4D42)
	{
		AfxMessageBox("File isn't a bmp file!");
		file.Close();
		return FALSE;
	}
	//读入信息头
	file.Read((LPSTR)&bi,sizeof(BITMAPINFOHEADER));
	//计算一行所需的字节数
	DWORD			   LineBytes;	//BMP图像中一行所需的数据长度
	LineBytes=(DWORD)WIDTHBYTES(bi.biWidth*bi.biBitCount);
	//计算整幅图像数据所需的内存空间
	DWORD 		       ImgSize;		//整幅图像数据所需的内存空间
	ImgSize=(DWORD)LineBytes*bi.biHeight;
		
	//颜色数
	DWORD          NumColors;	//用到的颜色数,if=0 then True color 24 bits
    if(bi.biClrUsed!=0)//直接指定颜色数
	{
		NumColors=(DWORD)bi.biClrUsed;
	}
	else	//根据图像深度计算颜色数
	{
        switch(bi.biBitCount)
		{
       	    case 1:
        	    NumColors=2;	//二值图像
				bi.biClrUsed=2;
        	    break;
        	case 4:
        	    NumColors=16;	//16色图像
				bi.biClrUsed=16;
        	    break;
        	case 8:
        	    NumColors=256;	//256色图像
				bi.biClrUsed=256;
        	    break;
        	case 24:
        	    NumColors=0;  //无调色板
        	    break;
            default:
                AfxMessageBox("Invalid color numbers!",MB_OK|MB_ICONEXCLAMATION);
                file.Close();
                return FALSE; 
        }
	}

	//判断图像的偏移地址是否正确
	if(bf.bfOffBits!=(DWORD)(sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+NumColors*sizeof(RGBQUAD)))
	{
		AfxMessageBox("Invalid color numbers!",MB_OK|MB_ICONEXCLAMATION);
		file.Close();
		return FALSE; 
	}
	//计算整个文件的大小
	bf.bfSize=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+NumColors*sizeof(RGBQUAD)+ImgSize;

	//内存数据区hImgData=包括位图信息头+颜色表+图象数据
	if(hImgData!=NULL)
	{
		GlobalUnlock(hImgData);
		GlobalFree(hImgData);  
		hImgData=NULL; 
	}
	if((hImgData=GlobalAlloc(GHND,(DWORD)(sizeof(BITMAPINFOHEADER)+NumColors*sizeof(RGBQUAD)+ImgSize)))==NULL)
	{
		AfxMessageBox("Error alloc memory!",MB_OK|MB_ICONEXCLAMATION);
	    file.Close();
		return FALSE;
	}

	////锁定内存数据区,将图像数据区内容读入内存
	LPBITMAPINFOHEADER lpImgData;	//原始逻辑位图信息头
	lpImgData=(LPBITMAPINFOHEADER)GlobalLock(hImgData);
	file.Seek(sizeof(BITMAPFILEHEADER),CFile::begin);
	file.Read((void *)lpImgData,(DWORD)(bf.bfSize-sizeof(BITMAPFILEHEADER)));
	file.Close();

	/////////////////////设置调色板/////////////////
	LOGPALETTE *pPal;   //逻辑调色板指针
	LPRGBQUAD	lpRGB;         
	HPALETTE	hPrevPalette;   //前一个调色板句柄
	HLOCAL		hPal;    
	if(hBitmap)
	{
		DeleteObject(hBitmap);
		hBitmap=NULL; 
	}
	if(hPalette)
	{
		hPalette=NULL; 
		DeleteObject(hPalette); 
	}
	if(NumColors)    //NumColors不为零,说明用到了调色板
	{ 
		//为逻辑调色板分配局部内存,大小为逻辑调色板结构长度加NumColors个PALETTENTRY
		hPal=LocalAlloc(LHND,sizeof(LOGPALETTE)+NumColors*sizeof(PALETTEENTRY));
		pPal=(LOGPALETTE *)LocalLock(hPal);  //指针pPal指向该内存区
		//填写逻辑调色板结构的头
		pPal->palNumEntries=(WORD)NumColors;
		pPal->palVersion=0x300;    //为什么是0x300?
		  //lpRGB指向的是调色板开始的位置
		lpRGB=(LPRGBQUAD)((LPSTR)lpImgData+(DWORD)sizeof(BITMAPINFOHEADER));
		  //填写每一项
		for(DWORD i=0;i<NumColors;i++)
		{
			pPal->palPalEntry[i].peRed=lpRGB->rgbRed;
			pPal->palPalEntry[i].peGreen=lpRGB->rgbGreen;
			pPal->palPalEntry[i].peBlue=lpRGB->rgbBlue;
			pPal->palPalEntry[i].peFlags=(BYTE) 0;
			lpRGB++;
		}
		hPalette=CreatePalette(pPal);   //调色板产生
		LocalUnlock(hPal);
		LocalFree(hPal);  //释放逻辑调色板空间
	}
	if(hPalette)
	{
		hPrevPalette=SelectPalette(pDC->m_hDC,hPalette,FALSE);
		RealizePalette(pDC->m_hDC);  //将现有逻辑调色板影射到系统调色板
	}
	hBitmap=CreateDIBitmap(pDC->m_hDC,(LPBITMAPINFOHEADER)lpImgData,(DWORD)CBM_INIT,
		(LPSTR)lpImgData+sizeof(BITMAPINFOHEADER)+NumColors*sizeof(RGBQUAD),
		(LPBITMAPINFO)lpImgData,DIB_RGB_COLORS);
	if(hPalette && hPrevPalette)
	{
		SelectPalette(pDC->m_hDC,hPrevPalette,FALSE);
		RealizePalette(pDC->m_hDC);   //将现有逻辑调色板影射到系统调色板
	}
    GlobalUnlock(hImgData);   //解锁内存数据区
	return TRUE;
}


/****************************************************************
 *
 * 函数名称:
 *  SaveBmpFile();
 *
 * 参数: 
 *  char *inFileName       加载图像的文件名  
 * 返回值:
 *   TRUE                  成功读取;
 *   FALSE                 失败;
 *
 * 说明:
 *    该函数读入图像文件文件数据到全局内存句柄hImgData中;
 *
 ****************************************************************/
BOOL MBmpClass::SaveBmpFile(CString fileName)
{
	CFile file;
	if(!(file.Open(fileName,CFile::modeCreate|CFile::modeWrite)))
	{
		AfxMessageBox("文件打开失败!",MB_OK|MB_ICONINFORMATION);
		return FALSE;
	}

    LPBITMAPINFOHEADER lpImgDatan;	//逻辑位图信息头
	lpImgDatan=(LPBITMAPINFOHEADER)GlobalLock(hImgData);

	//写文件头
	file.Write((char*)&bf,sizeof(bf));

	//写信息头 调色板 数据区
	file.Write( (char*)lpImgDatan,bf.bfSize-sizeof(BITMAPFILEHEADER));
	file.Flush();  //将输出缓冲区的数据送出,并清出。
	file.Close();

	GlobalUnlock(hImgData);		//解锁hImgData

	return TRUE;
}

⌨️ 快捷键说明

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