用c ++读取BMP文件的所有字节并旋转图片
Posted
技术标签:
【中文标题】用c ++读取BMP文件的所有字节并旋转图片【英文标题】:Reading all bytes of a BMP file in c++ and rotate picture 【发布时间】:2013-10-07 18:41:34 【问题描述】:我有一个 BMP 文件。我想读取它的所有字符并通过这些代码将图片旋转 90 cw。但是此代码仅适用于小图片,并且颜色已更改。我想将此代码用于 800*686 像素的图片。此代码不适用于它。我认为错误是在读取文件时,因为当我检查输入文件的字符向量时,在 59000 字节之后,向量中的所有字符都被 0 填充并且文件没有完全读取:
struct pixel
char blue;
char green;
char red;
;
int _tmain(int argc, _TCHAR* argv[])
//Reading file and save all into data vector
fstream fl("d://b.bmp");
ofstream fl2("d://b2.bmp");
fl.seekg(0,std::ios::end);
streampos length = fl.tellg();
vector<char> data(length);
fl.seekg(0,ios::beg);
fl.read(&data[0],length);
//make a string of bytes based on characters in "file" vector ,to calculate file features
byte intfile[54];
for(int i=0;i<54;i++)
if (data[i]<0)
intfile[i]=(256+data[i]);
else
intfile[i]=data[i];
//bpp is 2 bytes on 28,29 characters
short int bpp = intfile[28] | intfile[29] << 8;
//size of file is 4 bytes on 2,3,4,5 characters
unsigned int size= intfile[2] | intfile[3] << 8 | intfile[4] << 16 | intfile[5] << 24;
//offset of pixeles array is 4 bytes on 10,11,12,13 characters
unsigned int offset= intfile[10] | intfile[11] << 8 | intfile[12] << 16 | intfile[13] << 24;
//with is 4 bytes on 18,19,20,21 characters
unsigned int with= intfile[18] | intfile[19] << 8 | intfile[20] << 16 | intfile[21] << 24;
//height is 4 bytes on 22,23,24,25 characters
unsigned int height= intfile[22] | intfile[23] << 8 | intfile[24] << 16 | intfile[25] << 24;
//format of compression is 4 bytes on 30,31,32,33 characters
unsigned int format= intfile[30] | intfile[31] << 8 | intfile[32] << 16 | intfile[33] << 24;
//2D vector of pixels and filling it by data vector
vector< vector<pixel> > arrpix;
arrpix.resize(height);
for(int j=0;j<height;j++)
arrpix[j].resize(with);
int ix=offset;
for(int i=0;i<height;i++)
for(int j=0;j<with;j++)
arrpix[i][j].blue=data[ix++];
arrpix[i][j].green=data[ix++];
arrpix[i][j].red=data[ix++];
ix+=2;//padd
//2d new vector for making new rotated file
vector< vector<pixel> > arrpix2;
arrpix2.resize(with);
for(int j=0;j<with;j++)
arrpix2[j].resize(height);
for(int i=0;i<with;i++)
for(int j=0;j<height;j++)
arrpix2[i][j].blue=arrpix[j][with-1-i].blue;
arrpix2[i][j].green=arrpix[j][with-1-i].green;
arrpix2[i][j].red=arrpix[j][with-1-i].red;
//newsize
unsigned int news=(with*height*3)+54;//in rotation pad is not need because the new with is 800
//makeing new vector
vector<char> data2(news);
for(int i=0;i<news;i++)
data2[i]=data[i];
//change size
data2[5] = (news >> 24) & 0xFF;
data2[4] = (news >> 16) & 0xFF;
data2[3] = (news >> 8) & 0xFF;
data2[2] = news & 0xFF;
//replace height and with
for(int i=0;i<4;i++)
data2[18+i]=data[22+i];
data2[22+i]=data[18+i];
ix=offset;
//filling data by 2d new vector
for(int i=0;i<with;i++)
for(int j=0;j<height;j++)
data2[ix++]=arrpix2[i][j].blue;
data2[ix++]=arrpix2[i][j].green;
data2[ix++]=arrpix2[i][j].red;
fl2.write(&data2[0],news);
fl2.seekp(news,ios::beg);
fl2.close();
return 0;
【问题讨论】:
为什么数据是向量当您将文件重新定位到开头时,以实际读取我认为您想要的数据:
fl.seekg(0,ios::beg);
而不是
fl.seekg(length,ios::beg);
编辑:
阅读后添加以下代码:
if(f1.eof())
std::cerr << "Error reading file."
<< " Requested " << length << " bytes."
<< " Read " << f1.gcount() << bytes."
<< std::endl;
这应该告诉您代码认为文件有多大(根据实际文件大小验证),以及 f1 是否认为读取顺利。
您还应该在打开文件时使用 ios::binary 模式标志以二进制模式打开文件。
【讨论】:
以上是关于用c ++读取BMP文件的所有字节并旋转图片的主要内容,如果未能解决你的问题,请参考以下文章
用C语言编写程序处理图片bmp文件 1.读取图片的宽度,高度,每个像素所需的位数,水平分辨率,垂直
读bmp图片:头文件为66字节。。。怎么用c语言来读取数据啊,网上的代码我看不懂。新手,希望能写明白些