#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#include <ctype.h>
#include <process.h>
#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("D:\\a0.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("D:\\a0.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("D:\\a0.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<bmih.biHeight; i++)
{
k = 0;
for (j = 0; j<dwLineBytes24; j = j + 3)
{
NewImgData[k + i*dwLineBytes8] = 0.114*imgData[i*dwLineBytes24 + j] + 0.587*imgData[i*dwLineBytes24 + j + 1] + 0.299*imgData[i*dwLineBytes24 + j + 2];
k++;
}
}
for (i = 0; i<256; i++)
{
pal[i].rgbBlue = i;
pal[i].rgbGreen = i;
pal[i].rgbRed = i;
pal[i].rgbReserved = 0;
}
bf8.bfOffBits = bmfh.bfOffBits + 256 * sizeof(RGBQUAD);
bf8.bfReserved1 = 0;
bf8.bfReserved2 = 0;
bf8.bfSize = sizeof(BITMAPFILEHEADER) + dwLineBytes8*bmih.biHeight;
bf8.bfType = 19778;
bi8.biBitCount = 8;
bi8.biClrImportant = 0;
bi8.biClrUsed = 0;
bi8.biCompression = 0;
bi8.biHeight = bmih.biHeight;
bi8.biPlanes = 1;
bi8.biSize = 40;
bi8.biSizeImage = dwLineBytes8*bmih.biHeight;
bi8.biWidth = bmih.biWidth;
bi8.biXPelsPerMeter = 0;
bi8.biYPelsPerMeter = 0;
dataFile = fopen(filepath, "wb"); //以写的方式打开文件
if (!dataF