利用MFC简单的显示一个bmp图像

利用MFC简单的显示一个bmp图像,如有错误,欢迎指正

首先建立一个MFC AOOwizard(exe)单文档


然后插入一个基类,命名CDib


然后编辑Dib.cpp如下

// Dib.cpp: implementation of the CDib class.
//
//

#include "stdafx.h"
#include "test.h"
#include "Dib.h"

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

//
// Construction/Destruction:构造函数和析构函数
//

CDib::CDib()
{
	//成员初始化
	m_pDibData = NULL;
	m_pDibBits = NULL;
	m_pGrayScale = NULL;
	m_npoint.x=0;
	m_npoint.y=0;
 
}

CDib::CDib( CDib& Dib)
{
	CDib *pDib = &Dib;
	if (pDib == NULL)
	{
		return;
	}
	this->m_nDibSize = pDib->m_nDibSize;
	this->m_pDibData = new unsigned char[pDib->m_nDibSize];
	memset(this->m_pDibData,0,this->m_nDibSize);
	memcpy(this->m_pDibData,pDib->m_pDibData,m_nDibSize);
	m_pBitmapInfoHeader = (BITMAPINFOHEADER*)this->m_pDibData;
	m_nWidth = m_pBitmapInfoHeader->biWidth;
	m_nHeight = m_pBitmapInfoHeader->biHeight;
	this->m_npoint.x = 0;
	this->m_npoint.y = 0;
	if (m_pBitmapInfoHeader->biBitCount > 8)
	{
		m_nPaletteEntries = 0;
	} else
	{
		m_nPaletteEntries = 1 << m_pBitmapInfoHeader->biBitCount;
	}
	if (m_nPaletteEntries != 0)
	{
		m_pPaletteEntry = (PALETTEENTRY*)(m_pDibData+sizeof(BITMAPINFOHEADER));
	}else
	{
		m_pPaletteEntry = NULL;
	}
	m_pDibBits = m_pDibData + sizeof(BITMAPINFOHEADER) + m_nPaletteEntries * sizeof(RGBQUAD);
	m_nWidthBytes = WIDTHBYTES(m_nWidth*m_pBitmapInfoHeader->biBitCount);

	m_pGrayScale = NULL;
}

CDib::~CDib()//析构函数,用于释放内存空间
{
	if (m_pDibData != NULL)
	{
		delete []m_pDibData;
		m_pDibData = NULL;
		m_pDibBits = NULL;
	}
	if (m_pGrayScale != NULL)
	{
		delete []m_pGrayScale;
		m_pGrayScale = NULL;
	}

}

void CDib::LoadFile( const char* pFiLeName)
{
	if (m_pDibData != NULL)
	{
		delete []m_pDibData;
		m_pDibData = NULL;
		m_pBitmapInfoHeader = NULL;
		m_pDibBits = NULL;
		m_pPaletteEntry = NULL;
	}
	if (m_pGrayScale != NULL)
	{
		delete []m_pGrayScale;
		m_pGrayScale = NULL;
	} 

	CFile file;	//CFile 时MFC文件类的基类,具体用法可以参考MSDN
	if(!file.Open(pFiLeName,CFile::modeRead|CFile::shareDenyRead,NULL))
	{  //已读模式打开位图文件
		AfxMessageBox("File can't to be opened!",MB_OK);
		return;
	}
	BITMAPFILEHEADER BFH;
	file.Read(&BFH,sizeof(BITMAPFILEHEADER));
	if (BFH.bfType !='MB')//判断此文件是否是位图,Ox4d42代表BMP
	{
		AfxMessageBox("not a bitmap file!",MB_OK);
		return;
	}
	m_nDibSize = file.GetLength() - sizeof(BITMAPFILEHEADER);//计算除位图文件头的空间大小
	m_pDibData = new unsigned char[m_nDibSize]; //分配空间,并初始化为0
	memset(m_pDibData,0,m_nDibSize);//初始化内存,防止读出字符末尾出现乱码
	file.Read(m_pDibData,m_nDibSize); //读取除位图头文件的所有数据,需要了解Cfile的用法
	m_pBitmapInfoHeader = (BITMAPINFOHEADER*)m_pDibData;//设置位图指针信息
	m_nWidth = m_pBitmapInfoHeader->biWidth;
	m_nHeight = m_pBitmapInfoHeader->biHeight;
	m_nWidthBytes = WIDTHBYTES(m_nWidth*m_pBitmapInfoHeader->biBitCount);
	if (m_pBitmapInfoHeader->biBitCount > 8)
	{
		m_nPaletteEntries = 0;
		m_pPaletteEntry = NULL;
	} else
	{
		m_nPaletteEntries = 1 << m_pBitmapInfoHeader->biBitCount;
		m_pPaletteEntry = (PALETTEENTRY*)(m_pDibData+sizeof(BITMAPINFOHEADER));
	}
	m_pDibBits = m_pDibData + sizeof(BITMAPINFOHEADER) + m_nPaletteEntries * sizeof(RGBQUAD);
}

void CDib::Draw(CDC *pDC)//CDC *PDC表示设备环境指针
{
	if (m_pDibData != NULL)
	{
		::StretchDIBits(pDC->m_hDC,0,0,m_nWidth,m_nHeight,0,0,m_nWidth,m_nHeight,m_pDibBits,(BITMAPINFO*)m_pDibData,DIB_RGB_COLORS,SRCCOPY);
	}
	
}

void CDib::Draw( CDC *pDC, CRect rect)
{
	if (m_pDibData != NULL)
	{
		CPoint point;
		point.x = rect.CenterPoint().x-m_nWidth/2;
		point.y = rect.CenterPoint().y-m_nHeight/2;
		::StretchDIBits(pDC->m_hDC,point.x,point.y,m_nWidth,m_nHeight,0,0,m_nWidth,m_nHeight,m_pDibBits,(BITMAPINFO*)m_pDibData,DIB_RGB_COLORS,SRCCOPY);
	}
	
}

void CDib::Draw( CDC *pDC, CPoint point)
{
	if (m_pDibData != NULL)
	{
		::StretchDIBits(pDC->m_hDC,point.x,point.y,m_nWidth,m_nHeight,0,0,m_nWidth,m_nHeight,m_pDibBits,(BITMAPINFO*)m_pDibData,DIB_RGB_COLORS,SRCCOPY);
	}
	
}

void CDib::SaveFile(const char* pFileName)
{
	if (m_pDibData == NULL)
	{
		AfxMessageBox("No Opened file!",MB_OK);
		return;
	}
	CFile file;
	if (!file.Open(pFileName,CFile::modeCreate|CFile::modeWrite,NULL))
	{
		AfxMessageBox("Can't be created!",MB_OK);
		return;
	}
	BITMAPFILEHEADER BFH;
	BFH.bfOffBits = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+m_nPaletteEntries*sizeof(RGBQUAD);
	BFH.bfSize = sizeof(BITMAPFILEHEADER)+m_nDibSize;
	BFH.bfType = 'MB';
	file.WriteHuge(&BFH,sizeof(BITMAPFILEHEADER));
	file.WriteHuge(m_pDibData,m_nDibSize);
	file.Close();

}
然后编辑Dib.h头文件如下

// Dib.h: interface for the CDib class.
// 内容:设备无关位图类-头文件
// 功能:
//            位图的加载与保存
//			位图信息的获取
//			位图的显示
//			位图的转换
//			位图的相关判断	
//

#if !defined(AFX_DIB_H__59295F39_2E7D_4532_B8B8_FC19EF32EFF6__INCLUDED_)
#define AFX_DIB_H__59295F39_2E7D_4532_B8B8_FC19EF32EFF6__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#define WIDTHBYTES(i)((i+31)/32*4)

class CDib  
{
public:
	CDib();               //构造函数,初始化数据成员
	CDib(CDib&);
	virtual ~CDib();	// 析构函数,用于在撤销对象前,完成一些清理工作,如:释放内存空间等
 
public:
	void LoadFile(const char* );	//从文件加载位图
		//只有一个const,如果const位于*左侧,表示指针所指数据是常量,不能通过解引用修改该数据;指针本身是变量,可以指向其他的内存单元
	    //只有一个const,如果const位于*右侧,表示指针本身是常量,不能指向其他内存地址;指针所指的数据可以通过解引用修改。
		//两个const,*左右各一个,表示指针和指针所指数据都不能修改。
	void Draw(CDC*);
	void Draw(CDC*, CRect);
	void Draw(CDC*, CPoint);		//显示位图
	void SaveFile(const char* );	//将位图保存到文件
    
public:
	unsigned char* m_pDibData;
	unsigned char* m_pDibBits;
	long m_nDibSize;
	long m_nWidth,m_nHeight;
	BITMAPINFOHEADER* m_pBitmapInfoHeader;
	PALETTEENTRY* m_pPaletteEntry;
	long m_nPaletteEntries;
	long m_nWidthBytes;
    CPoint m_npoint;
	long *m_pGrayScale;


};

#endif // !defined(AFX_DIB_H__59295F39_2E7D_4532_B8B8_FC19EF32EFF6__INCLUDED_)
未完 待续

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值