程设作业:文件操作作业 解题报告&弱弱的代码
来源:互联网 发布:软件著作权和商标 编辑:程序博客网 时间:2024/06/11 14:06
解题报告:
做这道题要仔细阅读老师提供的文档,熟悉了24位位图的数据规模后再读入。
数据读入:对于图像数据分行读入,设置一个后移块,用于跳过每一行的补0位。
数据交换:a(width - i - 1,j) = b(j,i)
这里为了迎合题意,在main函数里加入两个参数int argc和char * argv[],这样可以直接从命令提示符cmd.exe中用如下图方式使用转换程序:
另外,代码里用到的template模板的思想来自thoar大牛的代码
大家可以去他的博客看到更多的代码:
http://blog.csdn.net/xranthoar
注意:老师提供的文档前面那篇文章可能有点问题,在图像描述信息块的最后一部分数据应该是002E-0035!
接下来贴代码:
因为手头没有32位位图,我不知道能不能旋转32位位图…
#include <iostream>#include <fstream>#pragma pack(1)using namespace std;const int CON_SIZE = 31; //公式中的大小。DataSizePerLine= (biWidth* biBitCount+31)/8;为一个扫描行所占的字节数const int BYTE_SIZE = 8; //一个字节=8位。typedef char BYTE; //1字节typedef short DBYTE; //2字节typedef int WORD; //4字节typedef long LONG; //4字节class FileHead //文件头信息块{public:DBYTE bfType; //文件标识,为字母ASCII码“BM”WORD bfSize; //文件大小WORD bfReserved; //保留,每字节以“00”填写WORD bfOffBits; //记录图像数据区的起始位置。各字节的信息依次含义为:文件头信息块大小,图像描述信息块的大小,图像颜色表的大小,保留(为01)};class InfoHead //图像描述信息块{public:WORD biSize; //图像描述信息块的大小,常为28HLONG biWidth; //图像宽度LONG biHight; //图像高度DBYTE biPlane; //图像的plane总数(恒为1)DBYTE biBitCount; //记录像素的位数,很重要的数值,图像的颜色数由该值决定WORD biCompression; //数据压缩方式(数值位0:不压缩;1:8位压缩;2:4位压缩)WORD biSizeImage; //图像区数据的大小LONG biXPelsPerMeter; //水平每米有多少像素,在设备无关位图(.DIB)中,每字节以00H填写LONG biYPelsPerMeter; //垂直每米有多少像素,在设备无关位图(.DIB)中,每字节以00H填写WORD biClrUsed; //此图像所用的颜色数WORD biCleImportance; //颜色重要性,若为0,则表示颜色一样重要//这里要注意!老师提供的文档前面那篇文章这里有错误,他说“002E-0031:此图像所用的颜色数,如值为0,表示所有颜色一样重要。”//但实际上:这里应该是两个长为4字节的数据!(即biClrUsed和biCleImportance)};class RGBQuad_24 //24位位图图像数据{public:RGBQuad_24() : rgbBlue(0), rgbGreen(0), rgbRed(0) { }; //补0用BYTE rgbBlue; //蓝BYTE rgbGreen; //绿BYTE rgbRed; //红};class RGBQuad_32 //32位位图图像数据{public:RGBQuad_32() : rgbBlue(0), rgbGreen(0), rgbRed(0), rgbAlpha(0) { }; //补0用BYTE rgbBlue; //蓝BYTE rgbGreen; //绿BYTE rgbRed; //红BYTE rgbAlpha; //透明度};FileHead Head;InfoHead Info;template <typename RGBQuad>bool Deal(ifstream &fin, ofstream &fout){RGBQuad *Quad;int LineSize = (Info.biWidth * Info.biBitCount + CON_SIZE) / BYTE_SIZE;LineSize -= LineSize % 4; //计算每一行的真实长度,在下面输入的时候用于过滤补0的数据int DifPtr = LineSize - Info.biWidth * sizeof(RGBQuad); //用于跳过补0数据int Scale = Info.biHight * Info.biWidth; //真实有用的数据规模Quad = new RGBQuad [Scale]; //生成图片数据包for(int i = 0; i != Info.biHight; ++i){fin.read((char*) (Quad + i * Info.biWidth), Info.biWidth * sizeof(RGBQuad)); //读入有效数据fin.seekg(DifPtr, ios::cur); //跳过补0位}FileHead DestHead = Head;InfoHead DestInfo = Info;DestInfo.biHight = Info.biWidth;DestInfo.biWidth = Info.biHight;int DestLineSize = (DestInfo.biWidth * DestInfo.biBitCount + CON_SIZE) / BYTE_SIZE;DestLineSize -= DestLineSize % 4;DifPtr = DestLineSize - DestInfo.biWidth * sizeof(RGBQuad); Scale = DestInfo.biWidth * DestInfo.biHight;DestHead.bfSize = DestInfo.biHight * DestLineSize + sizeof(FileHead) + sizeof(InfoHead);DestInfo.biSizeImage = DestHead.bfSize - sizeof(FileHead) + sizeof(InfoHead);RGBQuad *DestQuad = new RGBQuad [Scale];for(int i = 0; i != DestInfo.biHight; ++i){for(int j = 0; j != DestInfo.biWidth; ++j){DestQuad[(DestInfo.biHight - i - 1) * DestInfo.biWidth + j] = Quad[j * Info.biWidth + i];}} //交换数据fout.write((char *) &DestHead, sizeof(FileHead));fout.write((char *) &DestInfo, sizeof(InfoHead));char *Temp = new char[DifPtr + 1];memset(Temp, 0, DifPtr + 1);for(int i = 0; i != DestInfo.biHight; ++i){fout.write((char*) (DestQuad + DestInfo.biWidth * i), DestInfo.biWidth * sizeof(RGBQuad));fout.write((char*) Temp, DifPtr);}cout << "处理完成!" << endl;cout << "处理前文件大小 = " << Head.bfSize << endl;cout << "处理后文件大小 = " << DestHead.bfSize << endl;return true;}int main(int argc, char * argv[]) //传入控制台参数,在cmd里可以直接用rotatebmp src.bmp dest.bmp{if(argc == 1){argv[1] = "src.bmp";argv[2] = "dest.bmp"; //默认的图片文件名,缺省用}ifstream fin(argv[1], ios::in | ios::binary);ofstream fout(argv[2], ios::out | ios::binary);if(!fin){cout << "找不到 " << argv[1] << " !" << endl;return -1;}if(!fout){cout << "无法打开 " << argv[2] << " !" << endl;return -1;}fin.read((char *) &Head, sizeof(FileHead));fin.read((char *) &Info, sizeof(InfoHead)); //2进制读入两个文件信息头if(Info.biBitCount == 24){Deal<RGBQuad_24>(fin, fout);}if(Info.biBitCount == 32){Deal<RGBQuad_32>(fin, fout);}return 0;}
- 程设作业:文件操作作业 解题报告&弱弱的代码
- 数据结构与算法B代码编写作业,栈的基本操作,解题报告&AC代码
- [Ahoi2013]作业 解题报告
- 【作业解答】第一次上机作业解题报告
- 【作业解答】第二次上机作业解题报告
- 【作业解答】第三次上机作业解题报告
- 数据结构与算法B代码编写作业,树的转换,解题报告&AC代码
- 程设作业:模板
- 程设作业:MyString类
- C2第六次作业解题报告
- C2第四次作业解题报告
- C2第五次作业解题报告
- C2第七次作业解题报告
- 第十一周程序设计课作业解题报告
- 第十五周程序设计作业解题报告
- 数据结构与算法B代码编写作业,字符串插入,解题报告&AC代码
- 数据结构与算法B代码编写作业,位查询,解题报告&AC代码
- 数据结构与算法B代码编写作业,stack or queue,解题报告&AC代码
- POJ2231 Moo Volume [简单dp]
- PKU-文件操作作业-BMP图像文件旋转
- NYOJ 503 & HDU 2199 解方程(二分)
- Java编程规范整理
- [DSP(TI)]深入OSS开发
- 程设作业:文件操作作业 解题报告&弱弱的代码
- 子午流注和五运六气windows版安卓版ASP网页版
- python 中的赋值操作,与c/c++的对比
- 创业之必须
- C# 数组的基本用法
- 【HTML+CSS+JavaScript】网页实战开发笔记之一——HTML的头部信息里你不知道的事
- 【Android自学笔记】对应资源文件夹中的图标尺寸
- 博客之路
- poj 1187 陨石的秘密