WinLin

Flying int the sky,I will forget myself.

用户操作
[即时聊天] [发私信] [加为好友]
winlin398510617ID:winlin398510617
72739次访问,排名1483,好友0人,关注者2人。
winlin398510617的文章
原创 49 篇
翻译 2 篇
转载 0 篇
评论 209 篇
winlin398510617的公告
最近评论
瓶子:你不遗弃又有什么用呢?
涂一抹藤:弟弟,来看你。
我最近有点僵尸~
瓶子碎了:僵尸多好,一甩头,然后亮出两颗闪闪发亮的犬牙,表情认真,帅呀~
三部中,就最记得一个嫦娥,碧海青天夜夜心,算是深刻认识到了。
goldankye:老顽固处于嫉妒压抑之中,虽然看不懂什么意思,^_^
江南山鹰:不错!顶!
文章分类
    收藏
      相册
      大学同学
      fengshurui
      姜伟
      封朋成
      杨觅
      陈佳
      高中同学
      丁美艳
      帅石林
      彭拓
      王志峰
      陈焕鹏
      朋友
      bella
      zoujun
      上海老树
      金旭亮老师
      龙佐
      学工部团队
      冯尔钦
      凌艺
      刘洋
      吴伟周
      周娟娟
      张宁
      李文
      杨群
      段丽敏
      潘荣辉
      田晓锋
      谭清华
      邹定南
      鲍晓辉
      黄文强
      中勤的牛和人
      aries.net
      winlin2003
      winlin2004
      光华
      刘硕果
      周鹏
      小小
      小易
      小欣
      张先松
      晏小辉
      林泰山
      樊宏超
      游晶
      然然
      狂笨
      瓶子碎了
      盛谢华
      范禄承
      薛亮
      邵冲
      郎兵
      马炎
      存档
      软件项目交易
      订阅我的博客
      XML聚合  FeedSky
      订阅到鲜果
      订阅到Google
      订阅到抓虾
      订阅到BlogLines
      订阅到Yahoo
      订阅到GouGou
      订阅到飞鸽
      订阅到Rojo
      订阅到newsgator
      订阅到netvibes

      原创 位图格式分析收藏

      新一篇: 祭2007.5.1 | 旧一篇: 4月,万事俱备

      位图格式分析

      2007-4-16,杨成立

      目录

      位图格式分析... 1

      .位图文件存储格式... 1

      .BitmapFileHeader 2

      .BitmapInfo. 3

      .BitmapInfoHeader 3

      .BitmapData. 4

      .保存位图为文件... 4

      1. 错误信息函数... 4

      2. 建立位图信息结构体函数... 4

      3. 建立位图文件函数... 5

      4. 保存位图到文件函数... 6

      .从文件加载位图... 7

      1.错误信息函数... 7

      2. 从位图文件加载图象函数... 7

       

      .位图文件存储格式

      位图文件存储格式请参考图1.1

      1.1 位图文件存储格式

      图说明请参考表1.1

      1.1 位图文件存储格式说明

      结构体

      说明

      BitmapFileHeader

      位图文件信息头

      BitmapInfo

      位图信息,由以下两个结构体组成

      BitmapInfoHeader

      位图信息头

      RGBQUAD

      颜色表

      BitmapData

      位图数据

      .BitmapFileHeader

      typedef struct tagBITMAPFILEHEADER { // bmfh

          WORD    bfType;

          DWORD   bfSize;

          WORD    bfReserved1;

          WORD    bfReserved2;

          DWORD   bfOffBits;

      } BITMAPFILEHEADER;

      bfType:文件类型,0x4d42,也就是BM

      bfSize:文件大小,计算方法是
      位图文件头大小【sizeof(BITMAPFILEHEADER)
      +
      位图信息头大小【pbih->biSize
      +
      颜色表大小【pbih->biClrUsed*sizeof(RGBQUAD)
      +
      位图数据大小【pbih->biSizeImage

      bfReserved1:预留字段,为0

      bfReserved2:预留字段,为0

      bfOffBits:图象数据的偏移量,计算方法是
      位图文件头大小【sizeof(BITMAPFILEHEADER)
      +
      位图信息头大小【pbih->biSize
      +
      颜色表大小【pbih->biClrUsed*sizeof(RGBQUAD)

       

      .BitmapInfo

      typedef struct tagBITMAPINFO { // bmi

          BITMAPINFOHEADER bmiHeader;

          RGBQUAD          bmiColors[1];

      } BITMAPINFO;

      bmiHeader:位图信息头,见下节的结构体说明。

      bmiColorsRGB颜色表数组。一般不存储到位图,在GetDIBits时将丢失这个信息,biClrUsed将被设置为0

       

      .BitmapInfoHeader

      typedef struct tagBITMAPINFOHEADER{ // bmih

          DWORD  biSize;

          LONG   biWidth;

          LONG   biHeight;

          WORD   biPlanes;

          WORD   biBitCount

          DWORD  biCompression;

          DWORD  biSizeImage;

          LONG   biXPelsPerMeter;

          LONG   biYPelsPerMeter;

          DWORD  biClrUsed;

          DWORD  biClrImportant;

      } BITMAPINFOHEADER;

      biSize:结构体大小。

      biWidth:位图宽度,象素。对应位图宽度,bmp.bmWidth

      biHeight:位图高度,象素。对应位图高度,bmp.bmHeight

      biPlanes:调色板数目,一般是1。对应位图调色板数目,bmp.bmPlanes

      biBitCount:颜色位数。对应位图bmp.bmBitsPixel

      biClrUsed:使用的颜色数,在24位以下时需要使用,计算方法
      if(cClrBits < 24) pbmi->bmiHeader.biClrUsed=(1<<cClrBits);

      biSizeImage:图象数据大小,计算方法
      位图宽度象素数目转换成字节【(pbmi->bmiHeader.biWidth+7)/8
      *
      位图高度象素数目【pbmi->bmiHeader.biHeight
      *
      象素位数【cClrBits

      注:宽度象素数目+7再除以8,用来处理余数的情况,如位图宽度为2,除以80,所以要+7再除以8

      .BitmapData

      24位位图图象数据的存储是RGB序列,在windows中是BGR序列:

      象素B蓝色分量值

      象素G绿色分量值

      象素R红色分量值

      32位位图象素数据的存储是RGBA序列,AAlpha值,windowsBGRA序列:

      象素B蓝色分量值

      象素G绿色分量值

      象素R红色分量值

      象素alpha分量值

      16位图象的分布是:

      最高位保留,为0

      5位,红色分量

      中间5位,绿色分量

      最低5位,蓝色分量

       

      .保存位图为文件

      可以将程序中的图象保存为文件,具体代码如下:

      1. 错误信息函数

      //错误信息

      void exitWND(LPCTSTR msg)

      {

           MessageBox(NULL,msg,"Error",0);

           exit(0);

      }

      2. 建立位图信息结构体函数

      //建立位图信息结构体

      PBITMAPINFO CreateBitmapInfoStruct(HBITMAP hBmp)

      {

           BITMAP bmp;

           if(!GetObject(hBmp,sizeof(BITMAP),&bmp))

               exitWND("Error when get object from hbitmap");

           //获取颜色位数

           WORD cClrBits;

           cClrBits=(WORD)(bmp.bmPlanes*bmp.bmBitsPixel);

           if(cClrBits == 1)

               cClrBits=1;

           else if(cClrBits <= 4)

               cClrBits=4;

           else if(cClrBits <= 8)

               cClrBits=8;

           else if(cClrBits <= 16)

               cClrBits=16;

           else if(cClrBits <= 24)

               cClrBits=24;

           else cClrBits=32;

           //分配位图信息结构体

           PBITMAPINFO pbmi;

           if(cClrBits != 24)

               pbmi=(PBITMAPINFO)

               LocalAlloc(LPTR,sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*(1<<cClrBits));

           else

               pbmi=(PBITMAPINFO)

               LocalAlloc(LPTR,sizeof(BITMAPINFOHEADER));                           

           //初始化位图结构体

           pbmi->bmiHeader.biSize=sizeof(BITMAPINFOHEADER);

           pbmi->bmiHeader.biWidth=bmp.bmWidth;

           pbmi->bmiHeader.biHeight=bmp.bmHeight;

           pbmi->bmiHeader.biPlanes=bmp.bmPlanes;

           pbmi->bmiHeader.biBitCount=bmp.bmBitsPixel;

           if(cClrBits < 24)

               pbmi->bmiHeader.biClrUsed=(1<<cClrBits);

           //不压缩位图

           pbmi->bmiHeader.biCompression=BI_RGB;

           //初始化图象数据大小

           pbmi->bmiHeader.biSizeImage=

               (pbmi->bmiHeader.biWidth+7)/8

               *pbmi->bmiHeader.biHeight

               *cClrBits;

           //所有的设备颜色都重要

           pbmi->bmiHeader.biClrImportant=0;

           //返回指针

           return pbmi;

      }

      3. 建立位图文件函数

      //建立位图文件

      void CreateBMPFile(LPTSTR pszFile,PBITMAPINFO pbi,HBITMAP hBmp,HDC hDC)

      {

           PBITMAPINFOHEADER pbih=(PBITMAPINFOHEADER)pbi;

           LPBYTE lpBits;

           lpBits=(LPBYTE)GlobalAlloc(GMEM_FIXED,pbih->biSizeImage);

           if(!lpBits)

               exitWND("error to global alloc memory");

           //获取位图图象数据

           GetDIBits(hDC,hBmp,0,(WORD)pbih->biHeight,lpBits,pbi,DIB_RGB_COLORS);

           //建立位图文件

           HANDLE hf;

           hf=CreateFile(pszFile,GENERIC_READ|GENERIC_WRITE,

               NULL,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);

           if(hf == INVALID_HANDLE_VALUE)

               exitWND("error to create file");

           //建立位图文件信息头

           BITMAPFILEHEADER hdr;

           hdr.bfType=0x4d42;

           hdr.bfSize=(DWORD)(sizeof(BITMAPFILEHEADER)+

               pbih->biSize+pbih->biClrUsed*sizeof(RGBQUAD)+

               pbih->biSizeImage);

           hdr.bfReserved1=0;

           hdr.bfReserved2=0;

           //计算位图数据偏移量

           hdr.bfOffBits=(DWORD)sizeof(BITMAPFILEHEADER)+

               pbih->biSize+pbih->biClrUsed*sizeof(RGBQUAD);

           //写入位图文件头

           DWORD wt;

           if(!WriteFile(hf,(LPVOID)&hdr,sizeof(BITMAPFILEHEADER),&wt,NULL))

               exitWND("error when write bitmap file header");

           //写入位图信息头

           if(!WriteFile(hf,(LPVOID)pbih,

               sizeof(BITMAPINFOHEADER)+pbih->biClrUsed*sizeof(RGBQUAD),

               &wt,NULL))

               exitWND("error when write bitmap info header and RGBquad");

           //写入位图数据

           if(!WriteFile(hf,(LPVOID)lpBits,pbih->biSizeImage,&wt,NULL))

               exitWND("error when write data");

           //关闭文件

           if(!CloseHandle(hf))

               exitWND("error when close file handle");

           //释放图象数据所占内存

           GlobalFree(lpBits);

      }

      4. 保存位图到文件函数

      //保存位图到文件

      void SaveBitmapFile(LPTSTR fileName,HWND hWnd,HBITMAP bmp)

      {

           PBITMAPINFO pbmi;

           pbmi=CreateBitmapInfoStruct(bmp);

           HDC hdc;

           hdc=GetDC(hWnd);

           CreateBMPFile(fileName,pbmi,bmp,hdc);

           ReleaseDC(hWnd,hdc);

      }

       

      .从文件加载位图

      从文件加载位图,用ReadFile定位文件需要使用OVERLAPPED,展开位图到DC使用StretchDIBits函数。代码如下:

      1.错误信息函数

      //错误信息

      void exitWND(LPCTSTR msg)

      {

           MessageBox(NULL,msg,"Error",0);

           exit(0);

      }

      2. 从位图文件加载图象函数

      //从位图文件加载图象

      HBITMAP LoadBitmapFile(LPCTSTR fileName,HWND hWnd)

      {

           //打开文件

           HANDLE hf;

           hf=CreateFile(fileName,GENERIC_READ,FILE_SHARE_READ,

               NULL,OPEN_EXISTING,FILE_FLAG_OVERLAPPED,NULL);

           if(hf == INVALID_HANDLE_VALUE){

               exitWND("error when open file handle");

               return 0x00;

           }

           //展开位图文件到DC

           DWORD read;

           //读取文件信息头

           BITMAPFILEHEADER bfh;

           OVERLAPPED olbfh;

           memset(&olbfh,0,sizeof(OVERLAPPED));

           olbfh.Offset=0;

           ReadFile(hf,&bfh,sizeof(bfh),&read,&olbfh);

           //读取位图信息

           BITMAPINFO bi;

           OVERLAPPED olbi;

           memset(&olbi,0,sizeof(OVERLAPPED));

           olbi.Offset=sizeof(BITMAPFILEHEADER);

           ReadFile(hf,&bi.bmiHeader,sizeof(bi.bmiHeader),&read,&olbi);

           //读取位图数据

           LPBYTE lpBits;

           lpBits=(LPBYTE)GlobalAlloc(GMEM_FIXED,bi.bmiHeader.biSizeImage);

           OVERLAPPED ollpbits;

           memset(&ollpbits,0,sizeof(OVERLAPPED));

           ollpbits.Offset=bfh.bfOffBits;

           ReadFile(hf,lpBits,bi.bmiHeader.biSizeImage,&read,&ollpbits);

           //建立和窗口关联的DC

           HDC hdc;

           hdc=GetDC(hWnd);

           HDC mem;

           mem=CreateCompatibleDC(hdc);

           //建立和DC关联的位图

           HBITMAP bmp;

           bmp=CreateCompatibleBitmap(hdc,bi.bmiHeader.biWidth,bi.bmiHeader.biHeight);

           SelectObject(mem,bmp);

           //DC中展开

           StretchDIBits(mem,

               0,0,bi.bmiHeader.biWidth,bi.bmiHeader.biHeight,

               0,0,bi.bmiHeader.biWidth,bi.bmiHeader.biHeight,

               (LPVOID)lpBits,&bi,DIB_RGB_COLORS,SRCCOPY);

           //清理工作

           GlobalFree(lpBits);

           DeleteDC(mem);

           ReleaseDC(hWnd,hdc);

           CloseHandle(hf);

           //返回位图对象

           return bmp;

      }

       

       

      发表于 @ 2007年04月18日 19:02:00|评论(loading...)|编辑

      新一篇: 祭2007.5.1 | 旧一篇: 4月,万事俱备

      评论:没有评论。

      发表评论  


      登录
      Csdn Blog version 3.1a
      Copyright © winlin398510617