逐像素编辑 bmp [C++]
Posted
技术标签:
【中文标题】逐像素编辑 bmp [C++]【英文标题】:Editing bmp pixel by pixel [C++] 【发布时间】:2015-12-11 22:42:51 【问题描述】:我想制作一个程序,它将拍摄一张图像并将每个像素的蓝色分量替换为 0。
所以我写了这个。我在文件夹中有一个 bmp 图像和它的副本,作为输入文件,我输入了原始文件的名称,作为输出名称,我编写了副本。但是当我在程序运行后尝试打开第二个时,它无法正常打开。有人可以帮忙吗?
#include <iostream>
#include <fstream>
#include <cstdlib>
using namespace std;
int main()
ifstream ifs;
ofstream ofs;
char input[80];
char output[80];
cout<<"Input file name"<<endl;
cin>>input;
ifs.open(input, ios::binary);
if(!ifs)
cout<<"Error in opening file"<<endl;
system("pause");
return 0;
cout<<"Output file name"<<endl;
cin>>output;
ofs.open(output, ios::binary);
ifs.seekg(2);
int file_size;
ifs.read((char*)&file_size, sizeof(int));
ofs<<"Bitmap size: "<<file_size<<"\r\n";
ifs.seekg(10);
int beg;
ifs.read((char*)&beg, sizeof(int));
ofs<<"Beggining of image: "<<beg<<"\r\n";
ifs.seekg(18);
int columns;
ifs.read((char*)&columns, sizeof(int));
ofs<<"Column number: "<<columns<<"\r\n";
ifs.seekg(22);
int rows;
ifs.read((char*)&rows, sizeof(int));
ofs<<"Row number: "<<rows<<"\r\n";
int image_size=0;
columns+=(3*columns)%4;
image_size=3*columns*rows;
ofs<<"Size of image"<<image_size<<"\r\n";
ifs.seekg(beg);
unsigned char R,G,B;
for(int i=beg; i<image_size+beg; i+=3)
ofs.seekp(i);
ofs<<char(0);
system("pause");
return 0;
【问题讨论】:
您是否尝试过如果您的程序只是复制文件会发生什么 - 将字节从输入写入输出而不进行修改? 几乎在代码末尾的 for 呢? Piotr - 不,我没有,但这是个好主意。我会 我对 BMP 格式了解不多,但是……它真的包含诸如“图像大小”或“行号:”之类的字符串吗? @PiotrAleksanderChmielowski 不,当然不是。 【参考方案1】:没有包含诸如“位图大小:”、“图像开头:”、“列号:”、“行号:”和“图像大小”之类的文本的图像文件格式。
即使有这样的文件格式,你不是在写“开始”,你在写“开始”,那是行不通的。计算机往往非常偏爱正确的拼写。
即使存在这样的文件格式,它也不会与您正在读取的文件格式相同,因为您正在读取偏移量 2 处的 int
并将其解释为某种文件大小,但是您没有在输出文件的偏移量 2 处写入任何大小。
因此,长话短说,您必须对正在阅读的文件格式有一个非常清晰的规范(您没有告诉我们任何相关内容),并且您还必须在书面上遵循完全相同的规范文件。
随心所欲地制定自己的文件格式规范是行不通的。
另外,在未来,请记住,在 *** 上,诸如“它无法正常打开”之类的短语不会被视为对技术问题的有效描述。具体说明正在发生的事情。
提示:您似乎试图通过寻找单个字节并用零覆盖它们来就地编辑文件。这不适用于空文件。将原始文件的全部内容复制到新文件名,然后在副本上查找和覆盖字节。
【讨论】:
这是我在课堂上得到的一个作业,在描述中它说例如 bmp 文件的大小在偏移量 2 处,文件中图像的开头在偏移量 10 处给出等. 它有效,因为它正确地读取了所有信息。抱歉,当我写“无法正常打开”时,我的意思是当我尝试使用默认的 Windows 图像查看器打开文件时,它会显示“Windows 无法打开图像”。 新文件名是bmp的副本,所以我不是在空文件上操作。我有一个我从中读取的,另一个我试图通过寻找单个字节并将它们替换为零来改变它们。 Mateusz,您正在提示用户为输入文件输入一个文件名,为输出文件输入另一个文件名,很明显,您正在使用两个不同的文件。您没有尝试将输入文件的内容复制到输出文件中,因此您正在操作一个必须假定为空的文件。 (它可能碰巧已经存在,但这无关紧要。)如果您的代码依赖于输出文件的先前存在,那么您绝对不会使用输入文件。 我必须为写“将原始文件复制到新文件名”而道歉,因为这不清楚。无法将文件复制到文件名。我的意思当然是“将输入文件的内容复制到输出文件中”。【参考方案2】:所以我将发表我的评论作为答案: 我不太了解 BMP 格式,但是……它真的包含诸如“图像大小”或“行号:”之类的字符串吗?
如果不是,请删除ofs<<"Beggining of image: "<<beg<<"\r\n";
等,我认为您的意思是cout
而不是ofs
。
【讨论】:
【参考方案3】:好吧,我不读取文件进行修改,而是将原始文件的全部内容复制到输出文件名并进行修改。谢谢大家,也谢谢迈克,我按照你的建议做了。
【讨论】:
Mateusz,这应该是评论,而不是答案。以上是关于逐像素编辑 bmp [C++]的主要内容,如果未能解决你的问题,请参考以下文章
使用 CImg 编辑 RGB 像素数据 - Visual C++ 2008