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 で割り切れるように、さらに 2 バイトを追加する必要があります。現時点では、行114 * 3 = 342ごとにバイトのピクセル データがあります。次の 4 で割り切れる数は344です。

したがって、各行の読み取りの最後に、余分な 2 バイトを読み取って破棄します。

一般に、余分なバイトは次のように計算できます。

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

この場合alignmentは 4 です。

メモリから、完全なスキャン幅 ( ) の値を含む必要があるヘッダーにフィールドがありますが、width * bytesPerPixel + extra簡単に計算できるため、正しいとは思わない方がよいでしょう。

ビットマップを保存するときは、このパディング ルールにも注意する必要があります。

于 2013-02-11T09:08:23.190 に答える
1

2 番目の forループは奇妙に見えます。私はそれがそうであるべきだと信じています:

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

また:

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