C中图像的负变换

时间:2013-02-11 08:59:43

标签: c image-processing bmp

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

Original Image

Negative Image

2 个答案:

答案 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--) {...}