C/C++ BMP(24位真彩色)图像处理(2)------图像の截取

来源:互联网 发布:如何在淘宝上发布宝贝 编辑:程序博客网 时间:2024/06/06 13:17
原文链接:http://blog.csdn.net/weixinhum/article/details/24681875

对上一篇博客《C/C++ BMP(24位真彩色)图像处理(1)------图像打开与数据区处理》的代码做小部分的修改,就可以进行BMP图像的截取操作,代码如下:

[cpp] view plain copy
print?
  1. #include <string.h>   
  2. #include <math.h>     
  3. #include <stdio.h>     
  4. #include <stdlib.h>     
  5. #include <malloc.h>  
  6.   
  7. #include<time.h>//时间相关头文件,可用其中函数计算图像处理速度  
  8.   
  9. #define   WIDTHBYTES(bits) (((bits)+31)/32*4)//用于使图像宽度所占字节数为4byte的倍数  
  10.   
  11. #define MYCUT_HEIGHT 100    //截取高度  
  12. #define MYCUT_WIDTH 100     //截取宽度  
  13. #define BEGIN_X 0           //截取位图开始位置X坐标  
  14. #define BEGIN_Y 0           //截取位图开始位置Y坐标  
  15.   
  16. typedef unsigned char  BYTE;  
  17. typedef unsigned short WORD;  
  18. typedef unsigned long  DWORD;  
  19. typedef long LONG;  
  20.   
  21. //位图文件头信息结构定义  
  22. //其中不包含文件类型信息(由于结构体的内存结构决定,要是加了的话将不能正确读取文件信息)  
  23.   
  24. typedef struct tagBITMAPFILEHEADER {  
  25. DWORD  bfSize;          //文件大小  
  26. WORD   bfReserved1;     //保留字,不考虑  
  27. WORD   bfReserved2;     //保留字,同上  
  28. DWORD  bfOffBits;       //实际位图数据的偏移字节数,即前三个部分长度之和  
  29. } BITMAPFILEHEADER;   
  30.   
  31. //信息头BITMAPINFOHEADER,也是一个结构,其定义如下:  
  32.   
  33. typedef struct tagBITMAPINFOHEADER{  
  34. //public:  
  35. DWORD   biSize;             //指定此结构体的长度,为40  
  36. LONG    biWidth;            //位图宽  
  37. LONG    biHeight;           //位图高  
  38. WORD    biPlanes;           //平面数,为1  
  39. WORD    biBitCount;         //采用颜色位数,可以是1,2,4,8,16,24,新的可以是32  
  40. DWORD   biCompression;      //压缩方式,可以是0,1,2,其中0表示不压缩  
  41. DWORD   biSizeImage;        //实际位图数据占用的字节数  
  42. LONG    biXPelsPerMeter;    //X方向分辨率  
  43. LONG    biYPelsPerMeter;    //Y方向分辨率  
  44. DWORD   biClrUsed;          //使用的颜色数,如果为0,则表示默认值(2^颜色位数)  
  45. DWORD   biClrImportant;     //重要颜色数,如果为0,则表示所有颜色都是重要的  
  46. } BITMAPINFOHEADER;   
  47.   
  48. void main()  
  49. {  
  50.     long now=0;  
  51.     now=clock();//存储图像处理开始时间  
  52.   
  53.     BITMAPFILEHEADER bitHead,writebitHead;  
  54.     BITMAPINFOHEADER bitInfoHead,writebitInfoHead;   
  55.     FILE* pfile;//输入文件  
  56.     FILE* wfile;//输出文件  
  57.   
  58.     char strFile[50]="E:\\testpicture\\1.bmp";//打开图像路径,BMP图像必须为24位真彩色格式  
  59.     char strFilesave[50]="E:\\testpicture\\2.bmp";//处理后图像存储路径  
  60.     pfile = fopen(strFile,"rb");//文件打开图像  
  61.     wfile = fopen(strFilesave,"wb");//打开文件为存储修改后图像做准备  
  62.   
  63.     //读取位图文件头信息  
  64.     WORD fileType;  
  65.     fread(&fileType,1,sizeof(WORD),pfile);  
  66.     fwrite(&fileType,1,sizeof(WORD),wfile);  
  67.     if(fileType != 0x4d42)  
  68.     {  
  69.         printf("file is not .bmp file!");  
  70.         return;  
  71.     }  
  72.     //读取位图文件头信息  
  73.     fread(&bitHead,1,sizeof(tagBITMAPFILEHEADER),pfile);  
  74.     writebitHead=bitHead;//由于截取图像头和源文件头相似,所以先将源文件头数据赋予截取文件头  
  75.     //读取位图信息头信息  
  76.     fread(&bitInfoHead,1,sizeof(BITMAPINFOHEADER),pfile);  
  77.     writebitInfoHead=bitInfoHead;//同位图文件头相似  
  78.   
  79.     writebitInfoHead.biHeight=MYCUT_HEIGHT;//为截取文件重写位图高度  
  80.     writebitInfoHead.biWidth=MYCUT_WIDTH;//为截取文件重写位图宽度  
  81.     int mywritewidth=WIDTHBYTES(writebitInfoHead.biWidth*writebitInfoHead.biBitCount);//BMP图像实际位图数据区的宽度为4byte的倍数,在此计算实际数据区宽度  
  82.     writebitInfoHead.biSizeImage=mywritewidth*writebitInfoHead.biHeight;//计算位图实际数据区大小  
  83.   
  84.     writebitHead.bfSize=54+writebitInfoHead.biSizeImage;//位图文件头大小为位图数据区大小加上54byte  
  85.     fwrite(&writebitHead,1,sizeof(tagBITMAPFILEHEADER),wfile);//写回位图文件头信息到输出文件  
  86.     fwrite(&writebitInfoHead,1,sizeof(BITMAPINFOHEADER),wfile);//写回位图信息头信息到输出文件  
  87.   
  88.     int width = bitInfoHead.biWidth;  
  89.     int height = bitInfoHead.biHeight;  
  90.     //分配内存空间把源图存入内存     
  91.     int l_width = WIDTHBYTES(width*bitInfoHead.biBitCount);//计算位图的实际宽度并确保它为4byte的倍数  
  92.     int write_width = WIDTHBYTES(writebitInfoHead.biWidth*writebitInfoHead.biBitCount);//计算写位图的实际宽度并确保它为4byte的倍数  
  93.   
  94.     BYTE    *pColorData=(BYTE *)malloc(height*l_width);//开辟内存空间存储图像数据  
  95.     memset(pColorData,0,height*l_width);     
  96.   
  97.     BYTE    *pColorDataMid=(BYTE *)malloc(mywritewidth*MYCUT_HEIGHT);//开辟内存空间存储图像处理之后数据  
  98.     memset(pColorDataMid,0,mywritewidth*MYCUT_HEIGHT);   
  99.   
  100.     long nData = height*l_width;  
  101.     long write_nData = mywritewidth*MYCUT_HEIGHT;//截取的位图数据区长度定义  
  102.       
  103.     //把位图数据信息读到数组里     
  104.     fread(pColorData,1,nData,pfile);//图像处理可通过操作这部分数据加以实现  
  105.   
  106.     //截取图像数据区操作,在操作过程中注意截取图像是否越界,可在此处加入代码进行越界处理  
  107.     for(int hnum=height-BEGIN_Y-MYCUT_HEIGHT;hnum<height-BEGIN_Y;hnum++)//由于BMP图像的数据存储格式起点是图像的左下角,所以需要进行坐标换算操作  
  108.         for(int wnum=BEGIN_X;wnum<BEGIN_X+MYCUT_WIDTH;wnum++)  
  109.         {  
  110.             int pixel_point=hnum*l_width+wnum*3;//数组位置偏移量,对应于图像的各像素点RGB的起点  
  111.             int write_pixel_point=(hnum-height+BEGIN_Y+MYCUT_HEIGHT)*mywritewidth+(wnum-BEGIN_X)*3;  
  112.             pColorDataMid[write_pixel_point]=pColorData[pixel_point];  
  113.             pColorDataMid[write_pixel_point+1]=pColorData[pixel_point+1];  
  114.             pColorDataMid[write_pixel_point+2]=pColorData[pixel_point+2];  
  115.         }  
  116.   
  117.     fwrite(pColorDataMid,1,write_nData,wfile);   //将处理完图像数据区写回文件  
  118.     fclose(pfile);  
  119.     fclose(wfile);  
  120.   
  121.     printf("图像处理完成\n");  
  122.     printf("运行时间为:%dms\n",int(((double)(clock()-now))/CLOCKS_PER_SEC*1000));//输出图像处理花费时间信息  
  123. }  





阅读全文
0 0
原创粉丝点击