C++读取BMP图的信息

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

猜你喜欢

转载自blog.csdn.net/sm16111/article/details/81231206