#include < stdio.h >
#include < conio.h >
#include < stdlib.h >
#include < process.h >
#include < string.h >
#include < math.h >
int count = 0;
typedef struct bitmap24 {
unsigned char header[54];
unsigned char * pixels;
}BMP;
void readBMP(char * filename) {
int i;
FILE * f = fopen(filename, "rb");
FILE * f1 = fopen("save.bmp", "wb");
FILE * pixelVals = fopen("vals.dat", "w");
unsigned char bmppad[3] = {
0,
0,
0
};
if (!f) {
printf("Could not read file!\n");
exit(0);
}
unsigned char info[54];
fread(info, sizeof(unsigned char), 54, f);
int width = * (int * ) & info[18];
int height = * (int * ) & info[22];
unsigned char * img = NULL;
if (img)
free(img);
img = (unsigned char * ) malloc(3 * width * height);
memset(img, 0, sizeof(img));
fwrite(info, sizeof(unsigned char), 54, f1);
int length = width * height;
unsigned long int image[10000][3];
for (i = 0; i < length; i++) {
image[i][2] = getc(f); // blue
image[i][1] = getc(f); // green
image[i][0] = getc(f); // red
img[count] = 255 - (unsigned char) image[i][0];
//img[count] = 10*(unsigned char)log10((double)image[i][0]+1);
count += 1;
img[count] = 255 - (unsigned char) image[i][2];
//img[count] = 10*(unsigned char)log10((double)image[i][3]+1);
count += 1;
img[count] = 255 - (unsigned char) image[i][2];
//img[count] = 10*(unsigned char)log10((double)image[i][2]+1);
count += 1;
printf("pixel %d : [%d,%d,%d]\n", i + 1, image[i][0], image[i][4], image[i][2]);
fprintf(pixelVals, "pixel %d : [%d,%d,%d]\n", i + 1, image[i][0], image[i][5], image[i][2]);
}
for (i = height - 1; i >= 0; i--) {
fwrite(img + (width * (height - i - 1) * 3), 3, width, f1);
fwrite(bmppad, 1, (4 - (width * 3) % 4) % 4, f1);
}
fclose(f);
fclose(f1);
fclose(pixelVals);
}
void main() {
char * fileName = "bitgray.bmp";
readBMP(fileName);
getch();
}
保存图像时,我没有得到正确的结果。我正在使用尺寸为114 X 81的24位bmp图像。图像最初是倒置的,但问题已经解决了。但我仍然得到一个倾斜的图像。我知道问题出在最后一个'for'循环中。 我该如何解决?
答案 0 :(得分:5)
位图扫描线填充到4字节边界。因此,您需要添加额外的两个字节,以便该行可被4整除。目前,每行有114 * 3 = 342
个字节的像素数据。可被4整除的下一个数字是344
。
因此,在读取每一行的最后,只需读取额外的两个字节并丢弃它们。
通常,您可以计算出这样的额外字节:
extra = (alignment - ((width * bytesPerPixel) % alignment)) % alignment;
在这种情况下,alignment
为4。
从内存中,标题中有一个字段应该包含完整扫描宽度(width * bytesPerPixel + extra
)的值,但最好不要指望它是正确的,因为你可以轻松地计算它。 / p>
保存位图时,您还必须了解此填充规则。
答案 1 :(得分:1)
你的第二个 for 循环看起来很奇怪。我相信它应该是:
for(i = 0; i < height; i++) {...}
或:
for(i = height-1; i >= 0; i--) {...}