2
#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”循环中。我应该如何解决?

原始图像

负面形象

4

2 回答 2

5

位图扫描线填充到 4 字节边界。因此,您需要添加额外的两个字节,以便该行可以被 4 整除。目前,114 * 3 = 342每行都有字节的像素数据。下一个能被 4 整除的数是344

因此,在读取每一行结束时,只需读取额外的两个字节并丢弃它们。

通常,您可以像这样计算出额外的字节:

extra = (alignment - ((width * bytesPerPixel) % alignment)) % alignment;

在这种情况下alignment是 4。

从内存中,标头中有一个字段应该包含完整扫描宽度 ( width * bytesPerPixel + extra) 的值,但最好不要期望它是正确的,因为您可以轻松计算它。

保存位图时还必须注意此填充规则。

于 2013-02-11T09:08:23.190 回答
1

你的第二个for循环看起来很奇怪。我认为应该是:

for(i = 0; i < height;  i++) {...}

或者:

for(i = height-1; i >= 0;  i--) {...}
于 2013-02-11T09:06:41.910 回答