加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

【数字图像处理】C++读取、旋转和保存bmp图像文件编程实现(彩色图)

(2013-11-04 15:43:42)
标签:

it

彩色图:

彩色图的处理和灰度图略有不一样。主要是像素数据不同。由于每行数据的字节数必须是4的整数倍,这个地方处理起来要比灰度图麻烦很多,多以暂时还 没做好。本程序的局限性就是只能处理尺寸是4的整数倍的图片,可以旋转任意角度(逆时针)。

参考代码:分两个文件:BmpRot.h和BmpRot.cpp

BmpRot.h:

 

  1. typedef unsigned char BYTE 
  2. typedef unsigned short WORD 
  3. typedef unsigned int DWORD 
  4. typedef long LONG 
  5.   
  6. //位图文件头定义;  
  7. //其中不包含文件类型信息(由于结构体的内存结构决定,  
  8. //要是加了的话将不能正确读取文件信息)  
  9. typedef struct  tagBITMAPFILEHEADER{  
  10.     //WORD bfType;//文件类型,必须是0x424D,即字符“BM”  
  11.     DWORD bfSize;//文件大小  
  12.     WORD bfReserved1;//保留字  
  13.     WORD bfReserved2;//保留字  
  14.     DWORD bfOffBits;//从文件头到实际位图数据的偏移字节数  
  15. }BITMAPFILEHEADER;  
  16.   
  17. typedef struct tagBITMAPINFOHEADER{  
  18.     DWORD biSize;//信息头大小  
  19.     LONG biWidth;//图像宽度  
  20.     LONG biHeight;//图像高度  
  21.     WORD biPlanes;//位平面数,必须为1  
  22.     WORD biBitCount;//每像素位数  
  23.     DWORD  biCompression; //压缩类型  
  24.     DWORD  biSizeImage; //压缩图像大小字节数  
  25.     LONG  biXPelsPerMeter; //水平分辨率  
  26.     LONG  biYPelsPerMeter; //垂直分辨率  
  27.     DWORD  biClrUsed; //位图实际用到的色彩数  
  28.     DWORD  biClrImportant; //本位图中重要的色彩数  
  29. }BITMAPINFOHEADER; //位图信息头定义  
  30.   
  31. typedef struct tagRGBQUAD{  
  32.     BYTE rgbBlue; //该颜色的蓝色分量  
  33.     BYTE rgbGreen; //该颜色的绿色分量  
  34.     BYTE rgbRed; //该颜色的红色分量  
  35.     BYTE rgbReserved; //保留值  
  36. }RGBQUAD;//调色板定义  
  37.   
  38. //像素信息  
  39. typedef struct tagIMAGEDATA  
  40.  
  41.     BYTE red;  
  42.     BYTE green;  
  43.     BYTE blue;  
  44. }IMAGEDATA;  

 

BmpRot.cpp:

 

  1. #include   
  2. #include "BmpRot.h"  
  3. #include "stdlib.h"  
  4. #include "math.h"  
  5. #include   
  6.   
  7. #define PI 3.14159//圆周率宏定义  
  8. #define LENGTH_NAME_BMP 30//bmp图片文件名的最大长度  
  9.   
  10. using namespace std;  
  11.   
  12. //变量定义  
  13. BITMAPFILEHEADER strHead;  
  14. RGBQUAD strPla[256];//256色调色板  
  15. BITMAPINFOHEADER strInfo;  
  16.   
  17. //显示位图文件头信息  
  18. void showBmpHead(BITMAPFILEHEADER pBmpHead){  
  19.     cout<<"位图文件头:"<<endl;  
  20.     cout<<"文件大小:"<<pBmpHead.bfSize<<endl;  
  21.     cout<<"保留字_1:"<<pBmpHead.bfReserved1<<endl;  
  22.     cout<<"保留字_2:"<<pBmpHead.bfReserved2<<endl;  
  23.     cout<<"实际位图数据的偏移字节数:"<<pBmpHead.bfOffBits<<endl<<endl;  
  24.  
  25.   
  26. void showBmpInforHead(tagBITMAPINFOHEADER pBmpInforHead){  
  27.     cout<<"位图信息头:"<<endl;  
  28.     cout<<"结构体的长度:"<<pBmpInforHead.biSize<<endl;  
  29.     cout<<"位图宽:"<<pBmpInforHead.biWidth<<endl;  
  30.     cout<<"位图高:"<<pBmpInforHead.biHeight<<endl;  
  31.     cout<<"biPlanes平面数:"<<pBmpInforHead.biPlanes<<endl;  
  32.     cout<<"biBitCount采用颜色位数:"<<pBmpInforHead.biBitCount<<endl;  
  33.     cout<<"压缩方式:"<<pBmpInforHead.biCompression<<endl;  
  34.     cout<<"biSizeImage实际位图数据占用的字节数:"<<pBmpInforHead.biSizeImage<<endl;  
  35.     cout<<"X方向分辨率:"<<pBmpInforHead.biXPelsPerMeter<<endl;  
  36.     cout<<"Y方向分辨率:"<<pBmpInforHead.biYPelsPerMeter<<endl;  
  37.     cout<<"使用的颜色数:"<<pBmpInforHead.biClrUsed<<endl;  
  38.     cout<<"重要颜色数:"<<pBmpInforHead.biClrImportant<<endl;  
  39.  
  40.   
  41.   
  42. int main(){  
  43.     char strFile[LENGTH_NAME_BMP];//bmp文件名  
  44.     IMAGEDATA *imagedata NULL;//动态分配存储原图片的像素信息的二维数组  
  45.     IMAGEDATA *imagedataRot NULL;//动态分配存储旋转后的图片的像素信息的二维数组  
  46.     int width,height;//图片的宽度和高度  
  47.     cout<<"请输入所要读取的文件名:"<<endl;  
  48.     cin>>strFile;  
  49.     FILE *fpi,*fpw;  
  50.     fpi=fopen(strFile,"rb");  
  51.     if(fpi != NULL){  
  52.         //先读取文件类型  
  53.         WORD bfType;  
  54.         fread(&bfType,1,sizeof(WORD),fpi);  
  55.         if(0x4d42!=bfType)  
  56.          
  57.             cout<<"the file is not bmp file!"<<endl;  
  58.             return NULL;  
  59.          
  60.         //读取bmp文件的文件头和信息头  
  61.         fread(&strHead,1,sizeof(tagBITMAPFILEHEADER),fpi);  
  62.         //showBmpHead(strHead);//显示文件头  
  63.         fread(&strInfo,1,sizeof(tagBITMAPINFOHEADER),fpi);  
  64.         //showBmpInforHead(strInfo);//显示文件信息头  
  65.   
  66.         //读取调色板  
  67.         for(unsigned int nCounti=0;nCounti
  68.          
  69.             //存储的时候,一般去掉保留字rgbReserved  
  70.             fread((char *)&strPla[nCounti].rgbBlue,1,sizeof(BYTE),fpi);  
  71.             fread((char *)&strPla[nCounti].rgbGreen,1,sizeof(BYTE),fpi);  
  72.             fread((char *)&strPla[nCounti].rgbRed,1,sizeof(BYTE),fpi);  
  73.             cout<<"strPla[nCounti].rgbBlue"<<strPla[nCounti].rgbBlue<<endl;  
  74.             cout<<"strPla[nCounti].rgbGreen"<<strPla[nCounti].rgbGreen<<endl;  
  75.             cout<<"strPla[nCounti].rgbRed"<<strPla[nCounti].rgbRed<<endl;  
  76.          
  77.   
  78.         width strInfo.biWidth;  
  79.         height strInfo.biHeight;  
  80.         imagedata (IMAGEDATA*)malloc(width height sizeof(IMAGEDATA));  
  81.         imagedataRot (IMAGEDATA*)malloc(2 width height sizeof(IMAGEDATA));  
  82.         //初始化原始图片的像素数组  
  83.         for(int 0;i height;++i)  
  84.          
  85.             for(int 0;j width;++j)  
  86.              
  87.                 (*(imagedata width j)).blue 0;  
  88.                 (*(imagedata width j)).green 0;  
  89.                 (*(imagedata  width j)).red 0;  
  90.              
  91.          
  92.         //初始化旋转后图片的像素数组  
  93.         for(int 0;i height;++i)  
  94.          
  95.             for(int 0;j width;++j)  
  96.              
  97.                 (*(imagedataRot width j)).blue 0;  
  98.                 (*(imagedataRot width j)).green 0;  
  99.                 (*(imagedataRot width j)).red 0;  
  100.              
  101.          
  102.         //fseek(fpi,54,SEEK_SET);  
  103.         //读出图片的像素数据  
  104.         fread(imagedata,sizeof(struct tagIMAGEDATA) width,height,fpi);  
  105.           
  106.         fclose(fpi);  
  107.      
  108.     else  
  109.      
  110.         cout<<"file open error!"<<endl;  
  111.         return NULL;  
  112.      
  113.   
  114.     //图片旋转处理  
  115.     int RotateAngle;//要旋转的角度数  
  116.     double angle;//要旋转的弧度数  
  117.     int midX_pre,midY_pre,midX_aft,midY_aft;//旋转所围绕的中心点的坐标  
  118.     midX_pre width 2;  
  119.     midY_pre height 2;  
  120.     midX_aft width;  
  121.     midY_aft height;  
  122.     int pre_i,pre_j,after_i,after_j;//旋转前后对应的像素点坐标  
  123.     cout<<"输入要旋转的角度(0度到360度,逆时针旋转):"<<endl;  
  124.     cin>>RotateAngle;  
  125.     angle 1.0 RotateAngle PI 180;  
  126.     for(int 0;i height;++i)  
  127.      
  128.         for(int 0;j width;++j)  
  129.          
  130.             after_i midY_aft;//坐标变换  
  131.             after_j midX_aft;  
  132.             pre_i (int)(cos((double)angle) after_i sin((double)angle) after_j) midY_pre;  
  133.             pre_j (int)(sin((double)angle) after_i cos((double)angle) after_j) midX_pre;  
  134.             if(pre_i >= && pre_i height && pre_j >= && pre_j width)//在原图范围内  
  135.                 *(imagedataRot width j) *(imagedata pre_i width pre_j);  
  136.          
  137.      
  138.   
  139.     //保存bmp图片  
  140.     if((fpw=fopen("b.bmp","wb"))==NULL)  
  141.      
  142.         cout<<"create the bmp file error!"<<endl;  
  143.         return NULL;  
  144.      
  145.     WORD bfType_w=0x4d42;  
  146.     fwrite(&bfType_w,1,sizeof(WORD),fpw);  
  147.     //fpw +=2;  
  148.     fwrite(&strHead,1,sizeof(tagBITMAPFILEHEADER),fpw);  
  149.     strInfo.biWidth width;  
  150.     strInfo.biHeight height;  
  151.     fwrite(&strInfo,1,sizeof(tagBITMAPINFOHEADER),fpw);  
  152.     //保存调色板数据  
  153.     for(unsigned int nCounti=0;nCounti
  154.      
  155.         fwrite(&strPla[nCounti].rgbBlue,1,sizeof(BYTE),fpw);  
  156.         fwrite(&strPla[nCounti].rgbGreen,1,sizeof(BYTE),fpw);  
  157.         fwrite(&strPla[nCounti].rgbRed,1,sizeof(BYTE),fpw);  
  158.      
  159.     //保存像素数据  
  160.     for(int =0;i height;++i)  
  161.      
  162.         for(int 0;j width;++j)  
  163.          
  164.             fwrite( &(*(imagedataRot width j)).red,1,sizeof(BYTE),fpw);//注意三条语句的顺序:否则颜色会发生变化  
  165.             fwrite( &(*(imagedataRot width j)).green,1,sizeof(BYTE),fpw);  
  166.             fwrite( &(*(imagedataRot width j)).blue,1,sizeof(BYTE),fpw);  
  167.          
  168.      
  169.     fclose(fpw);  
  170.   
  171.     //释放内存  
  172.     delete[] imagedata;  
  173.     delete[] imagedataRot;  
  174.  

 

转自CSDN 江南烟雨博客 在此表示感谢

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有