C 语言实现 24 位图转为 8 位灰度图
2010-05-28 11:50:26| 分类: 图像处理 |字号 订阅
#ifndef BMP_H_2_INCLUDED
#define BMP_H_2_INCLUDED
typedef unsigned short WORD;
typedef unsigned long DWORD;
typedef long LONG;
typedef unsigned char BYTE;
typedef struct tagBITMAPFILEHEADER
{ // bmfh
WORD
DWORD
WORD
WORD
DWORD
bfType;
bfSize;
bfReserved1;
bfReserved2;
bfOffBits;
}BITMAPFILEHEADER;
typedef struct tagBITMAPINFOHEADER
{ // bmih
DWORD biSize;
biWidth;
LONG
biHeight;
LONG
WORD
biPlanes;
WORD
biBitCount;
DWORD biCompression;
DWORD biSizeImage;
LONG
LONG
DWORD biClrUsed;
DWORD biClrImportant;
biXPelsPerMeter;
biYPelsPerMeter;
}BITMAPINFOHEADER;
typedef struct tagRGBQUAD
{ // rgbq
BYTE
BYTE
BYTE
BYTE
rgbBlue;
rgbGreen;
rgbRed;
rgbReserved;
}RGBQUAD;
typedef struct tagBITMAPINFO
{
BITMAPINFOHEADER bmiHeader;
RGBQUAD bmiColors[1];
}BITMAPINFO;
#endif // BMP_H_2_INCLUDED
#include
#include
#include
#include
#include
#include
#include "bmp_2.h"
BITMAPFILEHEADER bmfh;
BITMAPINFOHEADER bmih;
BITMAPFILEHEADER bf8;
BITMAPINFOHEADER bi8;
BYTE *imgData;
BYTE *NewImgData;
void readData();
int ReadFileHeader(BITMAPFILEHEADER *);
int ReadInfoHeader(BITMAPINFOHEADER *);
int ReadPixelData(BYTE *);
void PrintFileHeader(BITMAPFILEHEADER *);
void PrintInfoHeader(BITMAPINFOHEADER *);
LONG GetLineBytes(int,int);
int ConVerTo8BitGray(char *);
void readData()
{
int i,k,h;
DWORD dwLineBytes;
i = ReadFileHeader(&bmfh);
if(i == 0)
{
printf("Read file header successful!\n");
}
k = ReadInfoHeader(&bmih);
if(k == 0)
{
printf("Read info header successful!\n");
}
dwLineBytes = GetLineBytes(bmih.biWidth,bmih.biBitCount);
imgData = (BYTE*)malloc(dwLineBytes*bmih.biHeight*sizeof(BYTE));
h = ReadPixelData(imgData);
if(h == 0)
{
printf("Read pixel data successful!\n");
}
if(i==0&&k==0&&h==0)
{
printf("Read datas successful!\n");
}
}
int ReadFileHeader(BITMAPFILEHEADER *bmfh) //读文件头文件
{
FILE *dataFile;
dataFile = fopen("shuaige.bmp","r");
if(fread(&bmfh->bfType,sizeof(WORD),1,dataFile)!=1)
//读入文件头文件中的文件类型元
素
{
}
printf("Can not read bfType in the file header.\n");
fclose(dataFile);
return -1;
if(fread(&bmfh->bfSize,sizeof(DWORD),1,dataFile)!=1)
{
printf("Can not read bfSize in the file header.\n");
fclose(dataFile);
return -1;
}
//读入文件大小元素
if(fread(&bmfh->bfReserved1,sizeof(WORD),1,dataFile)!=1) //必须设置为 0
{
printf("Can not read bfReserved1 in the file header.\n");
fclose(dataFile);
return -1;
}
if(fread(&bmfh->bfReserved2,sizeof(WORD),1,dataFile)!=1) //必须设置为 0
{
printf("Can not read bfReserved2 in the file header.\n");
fclose(dataFile);
return -1;
}
if(fread(&bmfh->bfOffBits,sizeof(DWORD),1,dataFile)!=1) //从文件头开始到实际图像数据
之间的字节偏移量
{
}
printf("Can not read bfOffBits in the file header.\n");
fclose(dataFile);
return -1;
fclose(dataFile);
return 0;
}
int ReadInfoHeader(BITMAPINFOHEADER *bmih) //读信息头文件
{
FILE *dataFile;
dataFile = fopen("shuaige.bmp","r");
fseek(dataFile,14,SEEK_SET); //文件指针跳过文件头
if(fread(&bmih->biSize,sizeof(DWORD),1,dataFile)!=1) //读入信息头文件结构所需要的字
节数
{
}
printf("Can not read biSize in the info header.\n");
fclose(dataFile);
return -1;
if(fread(&bmih->biWidth,sizeof(LONG),1,dataFile)!=1) //读入图像宽度
{
printf("Can not read biWidth in the info header.\n");
fclose(dataFile);
return -1;
}
if(fread(&bmih->biHeight,sizeof(LONG),1,dataFile)!=1) //读入图像高度
{
printf("Can not read biHeight in the info header.\n");
fclose(dataFile);
return -1;
}
if(fread(&bmih->biPlanes,sizeof(WORD),1,dataFile)!=1) //读入位图平面数,总是设置为 1
{
printf("Can not read biPlanes in the info header.\n");
fclose(dataFile);
return -1;
}
if(fread(&bmih->biBitCount,sizeof(WORD),1,dataFile)!=1) //读入比特数,即位图的位数
{
printf("Can not read biBitCount in the info header.\n");
fclose(dataFile);
return -1;
}
if(fread(&bmih->biCompression,sizeof(DWORD),1,dataFile)!=1) //说明图像数据压缩类型
{
printf("Can not read biCompression in the info header.\n");
fclose(dataFile);
return -1;
}
if(fread(&bmih->biSizeImage,sizeof(DWORD),1,dataFile)!=1) //读入图像大小
{
printf("Can not read biSizeImage in the info header.\n");
fclose(dataFile);
return -1;
}
if(fread(&bmih->biXPelsPerMeter,sizeof(LONG),1,dataFile)!=1) //说明水平分辨率
{
printf("Can not read biXPelsPerMeter in the info header.\n");
fclose(dataFile);
return -1;
}
if(fread(&bmih->biYPelsPerMeter,sizeof(LONG),1,dataFile)!=1) //说明垂直分辨率
{
printf("Can not read biYPelsPerMeter in the info header.\n");
fclose(dataFile);
return -1;
}
if(fread(&bmih->biClrUsed,sizeof(DWORD),1,dataFile)!=1) //说明位图实际使用的彩色表中
颜色索引数
{
}
printf("Can not read biClrUsed in the info header.\n");
fclose(dataFile);
return -1;
if(fread(&bmih->biClrImportant,sizeof(DWORD),1,dataFile)!=1) //说明对图像显示有重要影
响的颜色索引数
{
}
printf("Can not read biClrImportant in the info header.\n");
fclose(dataFile);
return -1;
fclose(dataFile);
return 0;
}
int ReadPixelData(BYTE *imgData) //读取像素数据
{
BYTE *data;
FILE *dataFile;
DWORD dwLineBytes;
dwLineBytes = GetLineBytes(bmih.biWidth,bmih.biBitCount);
data = (BYTE *)malloc(dwLineBytes*bmih.biHeight*sizeof(BYTE));
dataFile = fopen("shuaige.bmp","rb");
if(bmih.biBitCount==8)
{
fseek(dataFile,bmfh.bfOffBits,SEEK_SET);
}
else if(bmih.biBitCount==24)
{
fseek(dataFile,bmfh.bfOffBits,SEEK_SET);
}
else
{
}
printf("Only Support: 8 or 24 bits.\n");
free(data);
fclose(dataFile);
return -1;
if(fread(data,dwLineBytes*bmih.biHeight*sizeof(BYTE),1,dataFile)!=1)
{
printf("Can not read the pixel data.\n");
free(data);
fclose(dataFile);
return -1;
}
memcpy(imgData,data,dwLineBytes*bmih.biHeight*sizeof(BYTE));
free(data);
fclose(dataFile);
return 0;
}
void PrintFileHeader(BITMAPFILEHEADER *ibmfh) //打印文件头信息
{
printf("The contents in the file header of the BMP file:\n");
printf("bfOffBits: %ld\n",ibmfh->bfOffBits);
printf("bfReserved1: %ld\n",ibmfh->bfReserved1);
printf("bfReserved2: %ld\n",ibmfh->bfReserved2);
printf("bfSize: %ld\n",ibmfh->bfSize);
printf("bfType: %ld\n",ibmfh->bfType);
}
void PrintInfoHeader(BITMAPINFOHEADER *ibmih) //打印信息头信息
{
printf("The content in the info header of the BMP file:\n");
printf("biBitCount: %ld\n",ibmih->biBitCount);
printf("biClrImportant: %ld\n",ibmih->biClrImportant);
printf("biClrUsed: %ld\n",ibmih->biClrUsed);
printf("biCompression: %ld\n",ibmih->biCompression);
printf("biHeight: %ld\n",ibmih->biHeight);
printf("biPlanes: %ld\n",ibmih->biPlanes);
printf("biSize: %ld\n",ibmih->biSize);
printf("biSizeImage: %ld\n",ibmih->biSizeImage);
printf("biWidth: %ld\n",ibmih->biWidth);
printf("biXPelsPerMeter: %ld\n",ibmih->biXPelsPerMeter);
printf("biYPelsPerMeter: %ld\n",ibmih->biYPelsPerMeter);
}
LONG GetLineBytes(int imgWidth,int bitCount) //计算每行像素所占的字节数
{
return (imgWidth*bitCount+31)/32*4;
}
int ConVerTo8BitGray(char *filepath) //24 位图转换 8 位图
{
int i,j,k;
FILE *dataFile;
DWORD dwLineBytes8;
DWORD dwLineBytes24;
RGBQUAD pal[256];
dwLineBytes24 = GetLineBytes(bmih.biWidth,24);
dwLineBytes8 = GetLineBytes(bmih.biWidth,8);
NewImgData = (BYTE *)malloc(dwLineBytes8*bmih.biHeight*sizeof(BYTE));
for(i=0; i