C++读取BMP图的信息
要读取BMP图信息首先要了解BMP图的构成,BMP图由文件头和信息头以及颜色表构成。
文件头:
typedef struct tagBITMAPFLEHEADER{
WORD bfType; //类型
DWORD bfSize; //大小
WORD bfReserved1; //位图保留字,必须为0
WORD bfReserved2; //位图保留字,必须为0
DWORD bfOffBits; //数据起启位置
}BITMAPFLEHEADER;
位图信息头:
typedef struct tagBITMAPINFOHEADER{
DWORD biSize; //占用字节数
LONG biWidth; //位图的宽度
LONG biHeight; //位图的高度
WORD biPlanes; //目标设备的级别,必须为1
WORD biBitCount; //每个像素所需的位数
DWORD biCompression; //位图压缩类型(0--不压缩,1--B1—RLE8压缩,2)
DWORD biSizeImage; //位图的大小
LONG biXPelsPerMeter; //水平分辨率
LONG biYPelsPerMeter; //垂直分辨率
DWORD biClrUsed; //实际使用的颜色表中的颜色数
DWORD biClrImportant; //显示过程中重要的颜色数。
}BITMAPINFOHEADER;
颜色表:(24位真彩色位图文件不含颜色表)
typedef struct tagRGBQUAD{
BYTE rgbBlue; //蓝色的亮度
BYTE rgbGreen;
BYTE rgbRed;
BYTE rgbReserved; //保留
}RGBQUAD;
下面上代码:
头文件ReadBmp.h
typedef unsigned char BYTE;
typedef unsigned short WORD;
typedef unsigned int DWORD;
typedef long LONG;
//位图文件头定义;
//其中不包含文件类型信息(由于结构体的内存结构决定,
//要是加了的话将不能正确读取文件信息)
typedef struct tagBITMAPFILEHEADER{
//WORD bfType;//文件类型,必须是0x4d42,即字符“BM”
DWORD bfSize;//文件大小
WORD bfReserved1;//保留字
WORD bfReserved2;//保留字
DWORD bfOffBits;//从文件头到实际位图数据的偏移字节数
}BITMAPFILEHEADER;
typedef struct tagBITMAPINFOHEADER{
DWORD biSize;//信息头大小
LONG biWidth;//图像宽度
LONG biHeight;//图像高度
WORD biPlanes;//位平面数,必须为1
WORD biBitCount;//每像素位数
DWORD biCompression; //压缩类型
DWORD biSizeImage; //压缩图像大小字节数
LONG biXPelsPerMeter; //水平分辨率
LONG biYPelsPerMeter; //垂直分辨率
DWORD biClrUsed; //位图实际用到的色彩数
DWORD biClrImportant; //本位图中重要的色彩数
}BITMAPINFOHEADER; //位图信息头定义
typedef struct tagRGBQUAD{
BYTE rgbBlue; //该颜色的蓝色分量
BYTE rgbGreen; //该颜色的绿色分量
BYTE rgbRed; //该颜色的红色分量
BYTE rgbReserved; //保留值
}RGBQUAD;//调色板定义
//像素信息
typedef struct tagIMAGEDATA
{
BYTE red;
BYTE green;
BYTE blue;
}IMAGEDATA;
源文件ReadBmp.cpp:
#include <stdio.h>
#include "ReadBmp.h"
#include "stdlib.h"
#include <iostream>
using namespace std;
//变量定义
BITMAPFILEHEADER strHead;
RGBQUAD strPla[256];//256色调色板
BITMAPINFOHEADER strInfo;
IMAGEDATA imagedata[256][256];//存储像素信息
//显示位图文件头信息
void showBmpHead(BITMAPFILEHEADER pBmpHead){
cout<<"位图文件头:"<<endl;
//cout<<"bfType value is "<<hex<<pBmpHead.bfType<<endl;
cout<<"文件大小:"<<pBmpHead.bfSize<<endl;
cout<<"保留字_1:"<<pBmpHead.bfReserved1<<endl;
cout<<"保留字_2:"<<pBmpHead.bfReserved2<<endl;
cout<<"实际位图数据的偏移字节数:"<<pBmpHead.bfOffBits<<endl<<endl;
}
void showBmpInforHead(tagBITMAPINFOHEADER pBmpInforHead){
cout<<"位图信息头:"<<endl;
cout<<"结构体的长度:"<<pBmpInforHead.biSize<<endl;
cout<<"位图宽:"<<pBmpInforHead.biWidth<<endl;
cout<<"位图高:"<<pBmpInforHead.biHeight<<endl;
cout<<"biPlanes平面数:"<<pBmpInforHead.biPlanes<<endl;
cout<<"biBitCount采用颜色位数:"<<pBmpInforHead.biBitCount<<endl;
cout<<"压缩方式:"<<pBmpInforHead.biCompression<<endl;
cout<<"biSizeImage实际位图数据占用的字节数:"<<pBmpInforHead.biSizeImage<<endl;
cout<<"X方向分辨率:"<<pBmpInforHead.biXPelsPerMeter<<endl;
cout<<"Y方向分辨率:"<<pBmpInforHead.biYPelsPerMeter<<endl;
cout<<"使用的颜色数:"<<pBmpInforHead.biClrUsed<<endl;
cout<<"重要颜色数:"<<pBmpInforHead.biClrImportant<<endl;
}
tagRGBQUAD* ReadFile(char *strFile){
FILE *fpi,*fpw;
int i,j;
fpi=fopen(strFile,"rb");
if(fpi!=NULL){
//先读取文件类型
WORD bfType;
fread(&bfType,1,sizeof(WORD),fpi);
if(0x4d42!=bfType){
cout<<"the file is not a bmp file!"<<endl;
return NULL;
}
//读取bmp文件的文件头和信息头
fread(&strHead,1,sizeof(tagBITMAPFILEHEADER),fpi);
showBmpHead(strHead);//显示文件头
fread(&strInfo,1,sizeof(tagBITMAPINFOHEADER),fpi);
showBmpInforHead(strInfo);//显示文件信息头
//读取调色板
/*for(int nCounti=0;nCounti<strInfo.biClrUsed;nCounti++){
//存储的时候,一般去掉保留字rgbReserved
fread((char *)&strPla[nCounti].rgbBlue,1,sizeof(BYTE),fpi);
fread((char *)&strPla[nCounti].rgbGreen,1,sizeof(BYTE),fpi);
fread((char *)&strPla[nCounti].rgbRed,1,sizeof(BYTE),fpi);
cout<<"strPla[nCounti].rgbBlue"<<strPla[nCounti].rgbBlue<<endl;
cout<<"strPla[nCounti].rgbGreen"<<strPla[nCounti].rgbGreen<<endl;
cout<<"strPla[nCounti].rgbRed"<<strPla[nCounti].rgbRed<<endl;
} */
//读出图片的像素数据
cout<<endl;
memset(imagedata,0,sizeof(IMAGEDATA) * 256 * 256);
//fseek(fpi,54,SEEK_SET);
fread(imagedata,sizeof(struct tagIMAGEDATA) * strInfo.biWidth,strInfo.biHeight,fpi);
for( i = 0;i < strInfo.biHeight;i++) {
for(int j = 0;j < strInfo.biWidth; j++){
printf("%d ", imagedata[i][j].red);
if(j==strInfo.biWidth-1)
cout<<endl;
}
}
/*cout<<"===================green====================="<<endl;
for( i = 0;i < strInfo.biHeight;i++) {
for( j = 0;j < strInfo.biWidth; j++){
printf("%d ", imagedata[i][j].green);
if(j==strInfo.biWidth-1)
cout<<endl;
}
}
cout<<"====================blue===================="<<endl;
for(i = 0;i < strInfo.biHeight;i++) {
for( j = 0;j < strInfo.biWidth; j++){
printf("%d ", imagedata[i][j].blue);
if(j==strInfo.biWidth-1)
cout<<endl;
}
} */
fclose(fpi);
}
else{
cout<<"file open error!"<<endl;
return NULL;
}
}
int main(){
char strFile[30] = "E:\\1.bmp";
cout<<strFile<<endl;
ReadFile(strFile);
system("pause"); //运行框闪退处理
}
具体可参考此链接:https://blog.csdn.net/xiajun07061225/article/details/5813726