BMP文件旋转

BMP文件旋转一 要求将 bmp 文件顺时针旋转 90 要求熟悉 BMP 的文件格式及熟悉文件操作解题思路如下 1 BMP 文件的组成此处不赘述 关键针对 24 位真彩图文件头组成 classHeader 文件头 public WORDbftype 位图文件的类型 必须为 BM DWORDbfsize 位图文件大小 以字节为单位 整个文件 包括位图与文件头和信息头 WORDbfRes

//一、要求将bmp文件顺时针旋转90°,要求熟悉BMP的文件格式及熟悉文件操作 //解题思路如下: //1.BMP文件的组成此处不赘述,关键针对24位真彩图 //文件头组成 class Header //文件头 { public: WORD bftype; //位图文件的类型,必须为“BM” DWORD bfsize; //位图文件大小,以字节为单位,整个文件,包括位图与文件头和信息头 WORD bfReserved1; //位图文件保留字,必须为0 WORD bfReserved2; //位图文件保留字,必须为0 DWORD bfOffBits; //位图数据的起始位置,以相对于位图文件头的偏移量表示,以字节为单位 }; /其中WORD等为自定义数据类型以配合文档说 typedef unsigned char BYTE; //BYTE为每个像素的RGB类,数值在0~255 typedef unsigned int DWORD; //四个字节 typedef unsigned short WORD; //两个字节 typedef long LONG; //四个字节 信息头组成 class Info //信息头 { public: DWORD biSize; //本类所用的字节数 LONG biWidth; //位图的宽度,以像素为单位 LONG biHeight; //位图的高度,以像素为单位 WORD biPlanes; //目标设备的平面数//不清,必须为1//什么 WORD biBitCount; //每个像素所需的位数,必须是1(双色),4(16色),8(256色)或24(真彩色)之一 DWORD biCompression; //位图压缩类型,必须是 0(不压缩),1(BI_RLE8压缩类型)或 2(BI_RLE4压缩类型)之一 DWORD biSizeImage; //位图的大小,以字节为单位 LONG biXPelsPerMeter; //位图水平分辨率,每米像素数 LONG biYPelsPerMeter; //位图垂直分辨率,每米像素数 DWORD biClrUsed; //位图实际使用的颜色表中的颜色数 DWORD biClrImportant; //位图显示过程中重要的颜色数 }; 这说明bmp高H,宽W,每个坐标下(x,y)有一个像素,其中像素有3个字节,分别为RGB 读写文件 int main(int argc,char* argv[]) { char* src_name; char* dest_name; if(argc == 1) { cout<<"use \"src.bmp\" as default input file name,use \"dest.bmp\" as default output file name\n"; src_name = new char[10]; dest_name = new char[10]; strcpy(src_name,"src.bmp"); strcpy(dest_name,"dest.bmp"); } else { src_name = argv[1]; dest_name = argv[2]; } Header fileHeader; Info infoHeader; ifstream infile(src_name,ios::in|ios::binary); if(!infile) { cout<<"读取文件失败"< 
  
    (infile,outfile,fileHeader,infoHeader); else Trans 
   
     (infile,outfile,fileHeader,infoHeader); return 0; } //首先将src.bmp的文件头和信息头读入到内存的fileHeader 和infoHeader位置 //然后再进行旋转操作函数 //旋转函数的编写 //首先要改变目标函数的文件头数据和信息头数据,这里主要是文件头的bfSize即位图文件的大小和信息头的biWidth \biHeight\ biSizeImage //其次要进行旋转操作,即改变位图旋转90°后的数据存储 //所以要先读入位图数据 //考虑到 //Windows 规定图像文件中一个扫描行所占的字节数必须是 4 的倍数(即以字为单位),不足的以 0 填充,图像文件中一个扫描行所占的字节数计算方法: //DataSizePerLine= (biWidth* biBitCount+31)/8;// 一个扫描行所占的字节数 //即对于原始文件,其每行的后面是有补零的,所以读取时应跳过这部分 //PS:为什么每行读取字节公式是这样计算的呢?这是因为Windows 规定图像文件中一个扫描行所占的字节数必须是 4 的倍数(即以字为单位),即每个扫描行/读取的位数必须为32的倍数,向上取整,不足补零,所以要加上32-1,则DataSizePerLine= (biWidth* biBitCount+31)/32*4; //则要计算每个扫描行的补零的字节数 //一种写法: int getDiff(Info & info) { int DataSizePerline = (info.biWidth * info.biBitCount+31) / 8; // 一个扫描行实际所占的字节数 DataSizePerline -= DataSizePerline % 4; //为什么要这行捏,DataSizePerline不是4的倍数吗 return DataSizePerline - info.biWidth * info.biBitCount /8; // } //另一种写法 int getDiff(Info & info) { return 4 - ((info.biWidth * info.biBitCount)/8)%4; //但是这种写法好像不能解决图片2 } //接下来便是旋转函数 template < class T > bool Trans(ifstream & infile,ofstream & outfile,Header & header,Info & info) { Header new_header = header; Info new_info = info; new_info.biWidth = info.biHeight; new_info.biHeight = info.biWidth; int diff = getDiff(info); T* pic = new T[info.biHeight * info.biWidth]; for(int i=0;i 
    
      #include 
     
       #include 
      
        #include 
       
         #pragma pack(1) using namespace std; typedef unsigned char BYTE; typedef unsigned int DWORD; typedef unsigned short WORD; typedef long LONG; class Header //文件头 { public: WORD bftype; //位图文件的类型,必须为“BM” DWORD bfsize; //位图文件大小,以字节为单位,整个文件,包括位图与文件头和信息头 WORD bfReserved1; //位图文件保留字,必须为0 WORD bfReserved2; //位图文件保留字,必须为0 DWORD bfOffBits; //位图数据的起始位置,以相对于位图文件头的偏移量表示,以字节为单位 }; class Info //信息头 { public: DWORD biSize; //本类所用的字节数 LONG biWidth; //位图的宽度,以像素为单位 LONG biHeight; //位图的高度,以像素为单位 WORD biPlanes; //目标设备的平面数//不清,必须为1//什么 WORD biBitCount; //每个像素所需的位数,必须是1(双色),4(16色),8(256色)或24(真彩色)之一 DWORD biCompression; //位图压缩类型,必须是 0(不压缩),1(BI_RLE8压缩类型)或 2(BI_RLE4压缩类型)之一 DWORD biSizeImage; //位图的大小,以字节为单位 LONG biXPelsPerMeter; //位图水平分辨率,每米像素数 LONG biYPelsPerMeter; //位图垂直分辨率,每米像素数 DWORD biClrUsed; //位图实际使用的颜色表中的颜色数 DWORD biClrImportant; //位图显示过程中重要的颜色数 }; class RGB24 { public: RGB24() { GREEN = 0; RED = 0; BLUE = 0; } BYTE RED; //红色的亮度(值范围在0~255) BYTE GREEN; //绿色的亮度(值范围在0~255) BYTE BLUE; //蓝色的亮度(值范围在0~255) }; /*找到每行需要补0的字节数 */ int getDiff(Info & info) { int DataSizePerline = (info.biWidth * info.biBitCount+31) / 8; // 一个扫描行实际所占的字节数 DataSizePerline -= DataSizePerline % 4; return DataSizePerline - info.biWidth * info.biBitCount / 8; //返回 } template < class T > bool Trans(ifstream & infile,ofstream & outfile,Header & header,Info & info) { Header new_header = header; Info new_info = info; new_info.biWidth = info.biHeight; new_info.biHeight = info.biWidth; int diff = getDiff(info); T* pic = new T[info.biHeight * info.biWidth]; for(int i=0;i 
        
          (infile,outfile,fileHeader,infoHeader); return 0; } 
         
        
       
      
     
    
  








版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/221384.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月17日 下午6:14
下一篇 2026年3月17日 下午6:14


相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号