用C语言作灰度变换,图片变成这样了,转换其他图片转换正常,以下为源码
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define getLineBytes(biWidth, biBitCount) (biWidth * biBitCount / 8 + 3) / 4 * 4;
#pragma pack(1)
typedef struct tagBITMAPFILEHEADER {
unsigned char bfType[2];
unsigned long bfSize;
unsigned short bfReserved1;
unsigned short bfReserved2;
unsigned long bfOffBits;
} fileHeader;
typedef struct tagBITMAPINFOHEADER {
unsigned long biSize;
long biWidth;
long biHeight;
unsigned short biPlanes;
unsigned short biBitCount;
unsigned long biCompression;
unsigned long biSizeImage;
long biXPixPerMeter;
long biYPixPerMeter;
unsigned long biClrUsed;
unsigned long biClrImportant;
} fileInfo;
typedef struct tagRGBQUAD {
unsigned char rgbBlue;
unsigned char rgbGreen;
unsigned char rgbRed;
unsigned char rgbReserved;
} rgbq;
void readBMP(FILE *fpBMP, fileHeader *fh, fileInfo *fi, rgbq *fq) {
fread(fh, sizeof(fileHeader), 1, fpBMP);
fread(fi, sizeof(fileInfo), 1, fpBMP);
long oldBiWidth = getLineBytes(fi->biWidth, fi->biBitCount);
fi->biBitCount = 8;
long newBiWidth = getLineBytes(fi->biWidth, fi->biBitCount);
fi->biSizeImage = newBiWidth * fi->biHeight;
fh->bfOffBits = sizeof(fileHeader) + sizeof(fileInfo) + 256 * sizeof(rgbq);
fh->bfSize = fh->bfOffBits + fi->biSizeImage;
for (int i = 0; i < 256; i++) {
fq[i].rgbBlue = fq[i].rgbGreen = fq[i].rgbRed = i;
}
}
void writeBMP(FILE *fpGray, fileHeader *fh, fileInfo *fi, rgbq *fq) {
fwrite(fh, sizeof(fileHeader), 1, fpGray);
fwrite(fi, sizeof(fileInfo), 1, fpGray);
fwrite(fq, sizeof(rgbq), 256, fpGray);
}
void convertToGray(FILE *fpBMP, FILE *fpGray, fileInfo *fi) {
unsigned char rgbImgData[3];
unsigned int grayImgData;
unsigned char rgbAnthor;
long oldBiWidth = getLineBytes(fi->biWidth, fi->biBitCount);
long newBiWidth = getLineBytes(fi->biWidth, 8);
for (int i = 0; i < fi->biHeight; i++) {
for (int j = 0; j < newBiWidth; j++) {
if (j < fi->biWidth)
{
for (int k = 0; k < 3; k++) {
fread(&rgbImgData[k], 1, 1, fpBMP);
}
grayImgData = (int)((float)rgbImgData[0] * 0.299 + (float)rgbImgData[1] * 0.587 + (float)rgbImgData[2] * 0.114);
}
else {
grayImgData = 0;
}
fwrite(&grayImgData,1, 1, fpGray);
}
for (int k = fi->biWidth * 3; k < oldBiWidth; k++) {
fread(&rgbAnthor, 1, 1, fpBMP);
}
}
}
int main() {
unsigned char bmpRGBPath[] = "test.bmp";
unsigned char bmpGrayPath[] = "gray.bmp";
FILE *fpBMP, *fpGray;
fileHeader fh;
fileInfo fi;
rgbq fq[256];
fpBMP = fopen(bmpRGBPath, "rb");
fpGray = fopen(bmpGrayPath, "wb");
readBMP(fpBMP, &fh, &fi, fq);
writeBMP(fpGray, &fh, &fi, fq);
convertToGray(fpBMP, fpGray, &fi);
fclose(fpGray);
fclose(fpBMP);
return 0;
}