反转BMP图片最终结果搞砸了

时间:2017-10-01 21:10:45

标签: c bmp

我正在尝试反转一个bmp文件并且接近获得正确的输出,但我不知道我哪里出错了。

[我的输出] [1]

与反转图像一样,原件为白色背景,黑色框,中间为x。但是,右上方没有黑线(我的输出在右上方附近有一条白线)。任何澄清将不胜感激。

执行反转的循环:

int index = 0;
while (index < dibHeader.width) {
    int index2 = 0;
    while (index2< dibHeader.length) {

        fread(&pixel.b, 1, 1, file);
        unsigned int blue = pixel.b;
        blue = ~blue;
        pixel.b = (char) blue;

        ... Same for green/red

        fseek(file, -3, SEEK_CUR);
        f(write(&pixel.b, 1, 1, file);

        ... Same for green/red

        index2++;
    }
    index++;
}

像素的结构:

struct Pixels {
    unsigned char b, g, r;
}

像素声明

struct Pixels pixel;

3 个答案:

答案 0 :(得分:1)

这里至少有两件事是可疑的:

首先,使用pixel.b = (char) blue,将无符号整数转换为char,然后再将其赋值给unsigned char。只需写下pixel.b = blue即可。

其次,每当你在阅读和写作之间进行切换时,即使你没有移动文件位置索引,也必须拨打fseek(或fflush)。否则行为未定义。因此,您必须在写完后引入fseek

index2++;
fseek(file, 0, SEEK_CUR);

请注意,您的程序需要以二进制模式打开文件,即"rb+"

答案 1 :(得分:1)

您张贴的图片宽度为273像素。您的代码似乎正在处理24位图像。必须填充24位图像的宽度,以确保它是4的倍数。

int padding = dibHeader.width % 4; 

位图从下到上逐行读取,然后逐列读取。在这种情况下,如果你从上到下都没关系,但你必须先遍历行和列,然后为每一行应用填充。

//24-bit image:
int padding = dibHeader.width % 4;
index = 0;
while(index < dibHeader.height) //<== go through the height
{
    index2 = 0;
    while(index2 < dibHeader.width) 
    {
        fread...
        pixel.r = ~pixel.r;
        pixel.b = ~pixel.b;
        pixel.g = ~pixel.g;

        fseek(f, -3, SEEK_CUR);
        fwrite...
        fflush(f);
        index2++;
    }
    fseek(f, padding, SEEK_CUR); //<== skip padding
    index++;
}

答案 2 :(得分:0)

我认为你需要改写这个:

unsigned int blue = pixel.b;
blue = ~blue;
pixel.b = (char) blue;

就此:

pixel.b ~= pixel.b;

并使用缓冲区进行数据处理。不需要读写几个字节。读取缓冲区中的所有数据,使用它们,然后将数据写入文件。另外,我在文件中写入数据后忘记了插入fseek(file, -3, SEEK_CUR);。但无论如何,使用缓冲区更强大,更完美。