实践代码
- 头文件
#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;
}