#include "header.h"
IMAGE *BmpRead(FILE* InBmp)
{
int n, x, y;
BITMAPFILEHEADER filehead;
BITMAPINFOHEADER bmi;
int width, height, BitCount, CompNum, compression;
int LineBytes;
unsigned char PadZeros[4];
unsigned char r, g, b;
IMAGE *image;
if (InBmp != NULL)
{
fseek(InBmp,0L,0); //把fp指针移动到离文件开头0字节处
fread(filehead.bfType,sizeof(char),1,InBmp); /* 读位图文件头 */
fread(filehead.bfType+sizeof(char),sizeof(char),1,InBmp);
if(1==1)
{
if(!(filehead.bfType[0]=='B'))
{
printf("文件不是BMP格式!\n");
return NULL;
}
else if(!(filehead.bfType[1]=='M'))
{
printf("文件不是BMP格式!\n");
return NULL;
}
}
fread(&filehead.bfSize,sizeof(int),1,InBmp);
fread(&filehead.bfReserved1,sizeof(short int),1,InBmp);
fread(&filehead.bfReserved2,sizeof(short int),1,InBmp);
fread(&filehead.bfOffBits,sizeof(int),1,InBmp);
fread(&bmi.biSize,sizeof(int),1,InBmp);
fread(&bmi.biWidth,sizeof(int),1,InBmp);
width = bmi.biWidth;
fread(&bmi.biHeight,sizeof(int),1,InBmp);
height = bmi.biHeight;
fread(&bmi.biPlanes,sizeof(short int),1,InBmp);
fread(&bmi.biBitCount,sizeof(short int),1,InBmp);
BitCount = bmi.biBitCount;
fread(&bmi.biCompression,sizeof(int),1,InBmp);
compression = bmi.biCompression;
fread(&bmi.biSizeImage,sizeof(int),1,InBmp);
fread(&bmi.biXPelspermeter,sizeof(int),1,InBmp);
fread(&bmi.biYPelspermeter,sizeof(int),1,InBmp);
fread(&bmi.biClrUsed,sizeof(int),1,InBmp);
fread(&bmi.biClrImportant,sizeof(int),1,InBmp);
LineBytes = (width * BitCount + 31) / 32 * 4;
if (compression != 0)
{
printf("不能读取压缩的文件!\n");
return NULL;
}
if (BitCount != 24)
{
printf("不能读取 %d 位图片!\n", BitCount);
return NULL;
}
if (BitCount == 24)
{
CompNum = 3;
if ((image = ImageAlloc(height, width, CompNum, BitCount)) == NULL)
{
printf("fail to allocate image.\n");
return NULL;
}
for (y = height - 1; y >= 0; y--)
{
for (x = 0; x < width; x++)
{
fread(&b, sizeof(unsigned char), 1, InBmp);
fread(&g, sizeof(unsigned char), 1, InBmp);
fread(&r, sizeof(unsigned char), 1, InBmp);
image->DataA[y * width + x] = b;
image->DataB[y * width + x] = g;
image->DataC[y * width + x] = r;
}
fread(PadZeros, sizeof(unsigned char), (LineBytes - width * 3), InBmp);
}
}
}
fclose(InBmp);
return image;
}
void BmpWriteTo256(FILE* OutBmp, IMAGE *image)
{
int x, y,i,m,n;
BITMAPFILEHEADER filehead = {'B','M',0,0,0,0};
BITMAPINFOHEADER bmi = {40,0,0,1,0,0,0,0,0,0,0};
RGBQUAD rgbout[256];
int height, width, BitCount, OffBits;
int LineBytes, PadBytes, BmpBytes, ImageBytes;
IMGDATATYPE TempGray;
unsigned char gray;
unsigned char PadZeros[4] = {0, 0, 0, 0};
height = image->height;
width = image->width;
BitCount = 8;
LineBytes = (width * BitCount + 31) / 32 * 4;
ImageBytes = LineBytes * height;
OffBits = 1078;
BmpBytes = OffBits + ImageBytes;
PadBytes = LineBytes - width;
if (OutBmp != NULL) {
filehead.bfType[0]='B';
fwrite(&filehead.bfType[0],sizeof(char),1,OutBmp);
filehead.bfType[1]='M';
fwrite(&filehead.bfType[1],sizeof(char),1,OutBmp);
filehead.bfSize=BmpBytes;
fwrite(&filehead.bfSize,sizeof(int),1,OutBmp);
filehead.bfReserved1=0;
fwrite(&filehead.bfReserved1,sizeof(short int),1,OutBmp);
filehead.bfReserved2=0;
fwrite(&filehead.bfReserved2,sizeof(short int),1,OutBmp);
filehead.bfOffBits = 1078;
fwrite(&filehead.bfOffBits,sizeof(int),1,OutBmp);
bmi.biSize=40;
fwrite(&bmi.biSize,sizeof(int),1,OutBmp);
bmi.biWidth = width;
fwrite(&bmi.biWidth,sizeof(int),1,OutBmp);
bmi.biHeight = height;
fwrite(&bmi.biHeight,sizeof(int),1,OutBmp);
bmi.biPlanes=1;
fwrite(&bmi.biPlanes,sizeof(short int),1,OutBmp);
bmi.biBitCount = 8;
fwrite(&bmi.biBitCount,sizeof(short int),1,OutBmp);
bmi.biCompression=0;
fwrite(&bmi.biCompression,sizeof(int),1,OutBmp);
bmi.biSizeImage=ImageBytes;
fwrite(&bmi.biSizeImage,sizeof(int),1,OutBmp);
bmi.biXPelspermeter = 0;
fwrite(&bmi.biXPelspermeter,sizeof(int),1,OutBmp);
bmi.biYPelspermeter = 0;
fwrite(&bmi.biYPelspermeter,sizeof(int),1,OutBmp);
bmi.biClrUsed = 0;
fwrite(&bmi.biClrUsed,sizeof(int),1,OutBmp);
bmi.biClrImportant = 0;
fwrite(&bmi.biClrImportant,sizeof(int),1,OutBmp);
for(i=0;i<256;i++)
{
rgbout[i].Blue = i;
fwrite(&rgbout[i].Blue,sizeof(char),1,OutBmp);
rgbout[i].Green = i;
fwrite(&rgbout[i].Green,sizeof(char),1,OutBmp);
rgbout[i].Red = i;
fwrite(&rgbout[i].Red,sizeof(char),1,OutBmp);
rgbout[i].Reserved = 0;
fwrite(&rgbout[i].Reserved,sizeof(char),1,OutBmp);
}
if (image->CompNum == 3)
{
for (y = height - 1; y >= 0; y--)
{
for (x = 0; x < width ; x++)
{
TempGray = ((image->DataC[y * width + x])*0.299 + (image->DataB[y * width + x])*0.587 + (image->DataA[y * width + x])*0.114 + 0.5) ;
TempGray = (IMGDATATYPE)ROUND(TempGray);
gray = (unsigned char)BOUND(TempGray, 0, 255);
fwrite(&gray, sizeof(char), 1, OutBmp);
}
fwrite(PadZeros, sizeof(unsigned char), PadBytes, OutBmp);
}
}
}
fclose(OutBmp);
}
IMAGE* ImageAlloc(int height, int width, int CompNum, int BitCount)
{
IMAGE* image;
if ((image = (IMAGE *) malloc (sizeof(IMAGE))) == NULL)
{
printf("fail to allocate memory image.\n");
return NULL;
}
if (CompNum == 1)
{
if ((image->gray = (IMGDATATYPE *) calloc (height * width, sizeof(IMGDATATYPE))) == NULL)
{
printf("fail to allocate image->gray.\n");
return NULL;
}
}
else if (CompNum == 3)
{
if ((image->DataA = (IMGDATATYPE *) calloc (height * width, sizeof(IMGDATATYPE))) == NULL)
{
printf("fail to allocate image->DataA.\n");
return NULL;
}
if ((image->DataB = (IMGDATATYPE *) calloc (height * width, sizeof(IMGDATATYPE))) == NULL)
{
printf("fail to allocate image->DataB.\n");
return NULL;
}
if ((image->DataC = (IMGDATATYPE *) calloc (height * width, sizeof(IMGDATATYPE))) == NULL)
{
printf("fail to allocate image->DataC.\n");
return NULL;
}
}
image->CompNum = CompNum;
image->height = height;
image->width = width;
image->BitCount = BitCount;
return image;
}
void ImageDealloc(IMAGE* image)
{
if (image->CompNum == 1)
{
free(image->gray);
}
else if (image->CompNum == 3)
{
free(image->DataA);
free(image->DataB);
free(image->DataC);
}
free(image);
}
main()
{
FILE *fin,*fout;
IMAGE *readdata;
fin=fopen("张晓庆.bmp","rb");
readdata = BmpRead(fin);
fout = fopen("新的256灰度图像名字.bmp","w+b");
BmpWriteTo256(fout, readdata);
ImageDealloc(readdata);
return 0;
}
- 1
- 2
前往页