BMP 颜色反转功能不起作用
Posted
技术标签:
【中文标题】BMP 颜色反转功能不起作用【英文标题】:Function for BMP color inverting doesn't work 【发布时间】:2015-01-30 02:58:39 【问题描述】:我编写了一些用于反转 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);
我错在哪里了?
【问题讨论】:
你试过1)读取数据,2)关闭文件并重新打开,3)保存数据。读取一个文件并同时更新它的内容是很棘手的,至少对我来说是这样。 我没试过。我通常不会尝试对我来说毫无意义的事情。 ..或者我不完全理解的事情。 why fseek or fflush is always required between reading and writing in the read/write "+" modes的可能重复 .bmp 文件的数据图像区域可以(并且通常是)大于像素像素数。首先是因为像素很少只有 1 个字节(大多数是 3 个字节)(可以从一个头块中的字段中读取此信息)其次因为每行必须计算到“可被 4 整除”的长度,这可以(通常)导致实际行长度长于像素像素长度计数。此外,偏移量 54 并非“一成不变”,而是可从第一个标头块中的一个字段中获得。 【参考方案1】:C11 草案规范对这个问题有这样的说法
当使用更新模式打开文件时('+' 作为第二个或第三个 上述模式参数值列表中的字符),输入和 可以在关联的流上执行输出。然而,输出 在没有介入调用的情况下,不应直接跟随输入 fflush 函数或文件定位函数(fseek、fsetpos、 或倒带),并且输入不得直接跟随输出而不 对文件定位函数的干预调用,除非输入 操作遇到文件结尾。
【讨论】:
谢谢。我不敢相信我错过了这个。好吧,我确实相信,因此我使用的是 C89,我读过的唯一参考资料来自 cpp。【参考方案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() 的结果,“旧”值似乎总是在读取 54 处的像素。我认为@RSahu 是正确的:不要像那样读写一个文件。最好将数据读入缓冲区,然后取反缓冲区,然后将其写入磁盘。或者完全写入不同的文件。
也许这与缓冲有关?
【讨论】:
以上是关于BMP 颜色反转功能不起作用的主要内容,如果未能解决你的问题,请参考以下文章