我正在尝试反转一个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;
答案 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);
。但无论如何,使用缓冲区更强大,更完美。