读取bmp格式数据--实践思考

实践代码

  • 头文件
#pragma once
#include <afx.h>
class DigitalImage 
{
private:
	//指针数据类型,需要动态分配数据大小,并初始化数据

	//文件头
	LPBITMAPFILEHEADER m_lpBitmapFileHender;

	//除位图文件头的所有数据
	LPBYTE m_lpNotFileHenderData;

	//文件信息头
	LPBITMAPINFOHEADER m_lpBitmapInfoHender;
	LPBITMAPINFO m_lpBitmapInfo;
	
	//颜色表
	LPRGBQUAD m_lpRgbQuad;
	RGBQUAD* RgbArray;

	//图像数据
	LPBYTE m_lpBmpData;

public:
	DigitalImage(LPCTSTR FileName);
	~DigitalImage();

};

  • .cpp文件
#include "DigitalImage.h"
#include<iostream>
#include<math.h>
using namespace std;

//构造函数,通过bmp(8位一下位图,即256色一下)位图的路劲来加载位图数据
DigitalImage::DigitalImage(LPCTSTR FileName)
{
	CFile RdBmp;
	//打开位图
	if (!RdBmp.Open(FileName, CFile::modeRead || CFile::shareDenyWrite))
		cout << "图像文件无法打开!" << endl;

	//申请文件头内存空间,用BYTE数组存储
	m_lpBitmapFileHender = (LPBITMAPFILEHEADER) new BYTE[sizeof(BITMAPFILEHEADER)];
	//初始化文件头
	memset(m_lpBitmapFileHender, 0, sizeof(BITMAPFILEHEADER));

	//读取文件头
	int FileHenderSize=RdBmp.Read((void*)m_lpBitmapFileHender, sizeof(BITMAPFILEHEADER));
	//判断是否读取了文件头
	if(FileHenderSize!= sizeof(BITMAPFILEHEADER))
		cout << "图像文件头读取错误!" << endl;

	//判断是否是位图图像
	if (m_lpBitmapFileHender->bfType == 0x4d42)//0x4d42=="BM",与是否是高字节在前还是低字节在前有关
	{
		//通过文件头获取图像文件大小
		DWORD FileSize = m_lpBitmapFileHender->bfSize;
		cout << "图像文件总字节数:" << FileSize << endl;
		
		//获取位图文件相对于文件头的偏移量
		DWORD of = m_lpBitmapFileHender->bfOffBits;

		//计算除文件头外,图像文件信息、包括文件信息头,颜色表和位图像素数据的总大小
		DWORD NotFileHenderSize = RdBmp.GetLength() - sizeof(BITMAPFILEHEADER);//GetLength()获取文件按字节计算的长度,而不是数量;
		
		//分配内存,读取数据,用于解析出来文件信息头,颜色表和像素数据
		m_lpNotFileHenderData = new BYTE[NotFileHenderSize];

		//初始化数组
		memset(m_lpNotFileHenderData, 0, NotFileHenderSize);

		//读取除文件头外的数据信息
		RdBmp.Read(m_lpNotFileHenderData, NotFileHenderSize);

		//关闭文件流
		RdBmp.Close();

		//通过m_lpNotFileHenderData数组获取文件信息头和文件信息结构体的起始地址。
		m_lpBitmapInfoHender =(LPBITMAPINFOHEADER) m_lpNotFileHenderData;
		m_lpBitmapInfo = (LPBITMAPINFO)m_lpNotFileHenderData; 

		//计算颜色表的起始位置
		m_lpRgbQuad = (LPRGBQUAD)(m_lpNotFileHenderData + m_lpBitmapInfoHender->biSize);

		//通过文件信息头判断位图中是使用的颜色数
		if (m_lpBitmapInfoHender->biClrUsed == 0)
			cout << "图像没有颜色表" << endl;
		else
		{
			//通过判断位图是几位位图,计算颜色数,
			int size = (int)pow(2, m_lpBitmapInfoHender->biBitCount);

			//分配颜色表数组
			RgbArray = new RGBQUAD[size];

			//通过颜色表的起始位置获取颜色数据存入颜色表数组
			for (int i = 0; i < size; i++)
			{
				RgbArray[i].rgbRed = m_lpRgbQuad->rgbRed;
				RgbArray[i].rgbGreen = m_lpRgbQuad->rgbGreen;
				RgbArray[i].rgbBlue = m_lpRgbQuad->rgbBlue;
				RgbArray[i].rgbReserved = 0;
				m_lpRgbQuad++;
			}

			//计算颜色表的字节长度
			DWORD RgbLen = size * sizeof(RGBQUAD);
			
			//颜色表之后即为图像像素的起始地址;
			m_lpBmpData = m_lpNotFileHenderData + m_lpBitmapInfoHender->biSize + sizeof(RgbArray);
		}
	}
	else
	{
		cout << "图像文件非BMP格式 !" << endl;
	}
}


DigitalImage::~DigitalImage()
{
	delete[] m_lpBitmapFileHender;
	delete[] m_lpNotFileHenderData;
	 m_lpBitmapInfoHender=NULL;
	 m_lpBitmapInfo=NULL;
	 m_lpRgbQuad=NULL;
	delete[] RgbArray;
	m_lpBmpData = NULL;
}
  • 主函数文件

#include "DigitalImage.h"
int main()
{
	//注意此处请更换问图片存储路径
	LPCTSTR filepath = "海王星.bmp";
	DigitalImage img(filepath);
	system("pause");
	return 0;
}

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

秘境之眼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值