我写了一些应该反转BMP图像颜色的快速代码。 我用40x40维BMP图像测试,由油漆创建。 然而,该功能似乎完全用白色像素填充它。
void
negate
(char *FILE_NAME)
{
FILE* fp = fopen(FILE_NAME, "r+b");
uint_64 raw_data, i;
fseek(fp, 35, SEEK_SET);
//raw_data = fgetc(fp) + fgetc(fp)*256;
raw_data = 4800; // calculated
fseek(fp, 54, SEEK_SET);
for(i = 54; i != 54 + raw_data; i++) // <=
{
int old = fgetc(fp);
fseek(fp, i, SEEK_SET);
fputc(255 - old, fp);
}
fclose(fp);
}
我错在哪里?
答案 0 :(得分:3)
C11草案规范有关于问题的说法
以更新模式打开文件时('+'作为第二个或第三个 上面的模式参数值列表中的字符),输入和 可以在关联的流上执行输出。但是,输出 在没有干预呼叫的情况下,不得直接输入 fflush功能或文件定位功能(fseek,fsetpos, 或倒带),输入不应直接跟随输出 除非输入,否则对文件定位功能进行干预调用 操作遇到文件结束。
答案 1 :(得分:2)
在循环中添加一个fseek修复了它,虽然我不明白为什么:
for (i = 54; i != 54 + raw_data; i++) // <=
{
fseek(fp, i, SEEK_SET);
int old = fgetc(fp);
fseek(fp, i, SEEK_SET);
fputc(255 - old, fp);
}
在试图找出问题时,我这样做,看看流中的位置是否正确:
for (i = 54; i != 54 + raw_data; i++) // <=
{
long x = ftell(fp);
printf("%d,", x);
int old = fgetc(fp);
fseek(fp, i, SEEK_SET);
fputc(255 - old, fp);
}
事实确实如此。它输出54,55,56,57,...所以fseek()不应该是必要的!但是如果你看一下fgetc()的结果,那么“old”值似乎总是在54读取像素。我认为@RSahu是正确的:不要像这样读写一个文件。最好将数据读入缓冲区,然后取消缓冲区,然后将其写入磁盘。或者完全写入不同的文件。
也许这与缓冲有关?