DIBAPI.CPP
上传用户:kennygump
上传日期:2022-07-22
资源大小:347k
文件大小:18k
源码类别:

图形/文字识别

开发平台:

Visual C++

  1. // ************************************************************************
  2. //  文件名:dibapi.cpp
  3. //
  4. //  公用 DIB(Independent Bitmap) API函数库:
  5. //
  6. //  PaintDIB()          - 绘制DIB对象
  7. //  FindDIBBits()       - 返回DIB图像象素起始位置
  8. //  DIBWidth()          - 返回DIB宽度
  9. //  DIBHeight()         - 返回DIB高度
  10. //  DIBNumColors()      - 计算DIB调色板颜色数目
  11. //  CopyHandle()        - 拷贝内存块
  12. //
  13. //  SaveDIB()           - 将DIB保存到指定文件中
  14. //  ReadDIBFile()       - 重指定文件中读取DIB对象
  15. //  NewDIB()            - 根据提供的宽、高、颜色位数来创建一个新的DIB
  16. //
  17. //  PaletteSize()       - 返回DIB调色板大小
  18. //
  19. // ************************************************************************
  20. #include "stdafx.h"
  21. #include "dibapi.h"
  22. #include <io.h>
  23. #include <errno.h>
  24. #include <math.h>
  25. #include <direct.h>
  26. /*
  27.  * Dib文件头标志(字符串"BM",写DIB时用到该常数)
  28.  */
  29. #define DIB_HEADER_MARKER   ((WORD) ('M' << 8) | 'B')
  30. /*************************************************************************
  31.  *
  32.  * 函数名称:
  33.  *   PaintDIB()
  34.  *
  35.  * 参数:
  36.  *   HDC hDC            - 输出设备DC
  37.  *   LPRECT lpDCRect    - 绘制矩形区域
  38.  *   HDIB hDIB          - 指向DIB对象的指针
  39.  *   LPRECT lpDIBRect   - 要输出的DIB区域
  40.  *   CPalette* pPal     - 指向DIB对象调色板的指针
  41.  *
  42.  * 返回值:
  43.  *   BOOL               - 绘制成功返回TRUE,否则返回FALSE。
  44.  *
  45.  * 说明:
  46.  *   该函数主要用来绘制DIB对象。其中调用了StretchDIBits()或者
  47.  * SetDIBitsToDevice()来绘制DIB对象。输出的设备由由参数hDC指
  48.  * 定;绘制的矩形区域由参数lpDCRect指定;输出DIB的区域由参数
  49.  * lpDIBRect指定。
  50.  *
  51.  ************************************************************************/
  52. BOOL WINAPI PaintDIB(HDC     hDC,
  53. LPRECT  lpDCRect,
  54. HDIB    hDIB,
  55. LPRECT  lpDIBRect,
  56. CPalette* pPal)
  57. {
  58. LPSTR    lpDIBHdr;            // BITMAPINFOHEADER指针
  59. LPSTR    lpDIBBits;           // DIB象素指针
  60. BOOL     bSuccess=FALSE;      // 成功标志
  61. HPALETTE hPal=NULL;           // DIB调色板
  62. HPALETTE hOldPal=NULL;        // 以前的调色板
  63. // 判断DIB对象是否为空
  64. if (hDIB == NULL)
  65. {
  66. // 返回
  67. return FALSE;
  68. }
  69. // 锁定DIB
  70. lpDIBHdr  = (LPSTR) ::GlobalLock((HGLOBAL) hDIB);
  71. // 找到DIB图像象素起始位置
  72. lpDIBBits = ::FindDIBBits(lpDIBHdr);
  73. // 获取DIB调色板,并选中它
  74. if (pPal != NULL)
  75. {
  76. hPal = (HPALETTE) pPal->m_hObject;
  77. // 选中调色板
  78. hOldPal = ::SelectPalette(hDC, hPal, TRUE);
  79. }
  80. // 设置显示模式
  81. ::SetStretchBltMode(hDC, COLORONCOLOR);
  82. // 判断是调用StretchDIBits()还是SetDIBitsToDevice()来绘制DIB对象
  83. if ((RECTWIDTH(lpDCRect)  == RECTWIDTH(lpDIBRect)) &&
  84.    (RECTHEIGHT(lpDCRect) == RECTHEIGHT(lpDIBRect)))
  85. {
  86. // 原始大小,不用拉伸。
  87. bSuccess = ::SetDIBitsToDevice(hDC,                    // hDC
  88.    lpDCRect->left,             // DestX
  89.    lpDCRect->top,              // DestY
  90.    RECTWIDTH(lpDCRect),        // nDestWidth
  91.    RECTHEIGHT(lpDCRect),       // nDestHeight
  92.    lpDIBRect->left,            // SrcX
  93.    (int)DIBHeight(lpDIBHdr) -
  94.   lpDIBRect->top -
  95.   RECTHEIGHT(lpDIBRect),   // SrcY
  96.    0,                          // nStartScan
  97.    (WORD)DIBHeight(lpDIBHdr),  // nNumScans
  98.    lpDIBBits,                  // lpBits
  99.    (LPBITMAPINFO)lpDIBHdr,     // lpBitsInfo
  100.    DIB_RGB_COLORS);            // wUsage
  101. }
  102.     else
  103. {
  104. // 非原始大小,拉伸。
  105. bSuccess = ::StretchDIBits(hDC,                          // hDC
  106.    lpDCRect->left,                 // DestX
  107.    lpDCRect->top,                  // DestY
  108.    RECTWIDTH(lpDCRect),            // nDestWidth
  109.    RECTHEIGHT(lpDCRect),           // nDestHeight
  110.    lpDIBRect->left,                // SrcX
  111.    lpDIBRect->top,                 // SrcY
  112.    RECTWIDTH(lpDIBRect),           // wSrcWidth
  113.    RECTHEIGHT(lpDIBRect),          // wSrcHeight
  114.    lpDIBBits,                      // lpBits
  115.    (LPBITMAPINFO)lpDIBHdr,         // lpBitsInfo
  116.    DIB_RGB_COLORS,                 // wUsage
  117.    SRCCOPY);                       // dwROP
  118. }
  119.     // 解除锁定
  120. ::GlobalUnlock((HGLOBAL) hDIB);
  121. // 恢复以前的调色板
  122. if (hOldPal != NULL)
  123. {
  124. ::SelectPalette(hDC, hOldPal, TRUE);
  125. }
  126. // 返回
  127. return bSuccess;
  128. }
  129. /*************************************************************************
  130.  *
  131.  * 函数名称:
  132.  *   FindDIBBits()
  133.  *
  134.  * 参数:
  135.  *   LPSTR lpbi         - 指向DIB对象的指针
  136.  *
  137.  * 返回值:
  138.  *   LPSTR              - 指向DIB图像象素起始位置
  139.  *
  140.  * 说明:
  141.  *   该函数计算DIB中图像象素的起始位置,并返回指向它的指针。
  142.  *
  143.  ************************************************************************/
  144. LPSTR WINAPI FindDIBBits(LPSTR lpbi)
  145. {
  146. return (lpbi + *(LPDWORD)lpbi + ::PaletteSize(lpbi));
  147. }
  148. /*************************************************************************
  149.  *
  150.  * 函数名称:
  151.  *   DIBWidth()
  152.  *
  153.  * 参数:
  154.  *   LPSTR lpbi         - 指向DIB对象的指针
  155.  *
  156.  * 返回值:
  157.  *   DWORD              - DIB中图像的宽度
  158.  *
  159.  * 说明:
  160.  *   该函数返回DIB中图像的宽度。对于Windows 3.0 DIB,返回BITMAPINFOHEADER
  161.  * 中的biWidth值;对于其它返回BITMAPCOREHEADER中的bcWidth值。
  162.  *
  163.  ************************************************************************/
  164. DWORD WINAPI DIBWidth(LPSTR lpDIB)
  165. {
  166. // 指向BITMAPINFO结构的指针(Win3.0)
  167. LPBITMAPINFOHEADER lpbmi;
  168. // 指向BITMAPCOREINFO结构的指针
  169. LPBITMAPCOREHEADER lpbmc;
  170. // 获取指针
  171. lpbmi = (LPBITMAPINFOHEADER)lpDIB;
  172. lpbmc = (LPBITMAPCOREHEADER)lpDIB;
  173. // 返回DIB中图像的宽度
  174. if (IS_WIN30_DIB(lpDIB))
  175. {
  176. // 对于Windows 3.0 DIB,返回lpbmi->biWidth
  177. return lpbmi->biWidth;
  178. }
  179. else
  180. {
  181. // 对于其它格式的DIB,返回lpbmc->bcWidth
  182. return (DWORD)lpbmc->bcWidth;
  183. }
  184. }
  185. /*************************************************************************
  186.  *
  187.  * 函数名称:
  188.  *   DIBHeight()
  189.  *
  190.  * 参数:
  191.  *   LPSTR lpDIB        - 指向DIB对象的指针
  192.  *
  193.  * 返回值:
  194.  *   DWORD              - DIB中图像的高度
  195.  *
  196.  * 说明:
  197.  *   该函数返回DIB中图像的高度。对于Windows 3.0 DIB,返回BITMAPINFOHEADER
  198.  * 中的biHeight值;对于其它返回BITMAPCOREHEADER中的bcHeight值。
  199.  *
  200.  ************************************************************************/
  201. DWORD WINAPI DIBHeight(LPSTR lpDIB)
  202. {
  203. // 指向BITMAPINFO结构的指针(Win3.0)
  204. LPBITMAPINFOHEADER lpbmi;
  205. // 指向BITMAPCOREINFO结构的指针
  206. LPBITMAPCOREHEADER lpbmc;
  207. // 获取指针
  208. lpbmi = (LPBITMAPINFOHEADER)lpDIB;
  209. lpbmc = (LPBITMAPCOREHEADER)lpDIB;
  210. // 返回DIB中图像的宽度
  211. if (IS_WIN30_DIB(lpDIB))
  212. {
  213. // 对于Windows 3.0 DIB,返回lpbmi->biHeight
  214. return lpbmi->biHeight;
  215. }
  216. else
  217. {
  218. // 对于其它格式的DIB,返回lpbmc->bcHeight
  219. return (DWORD)lpbmc->bcHeight;
  220. }
  221. }
  222. /*************************************************************************
  223.  *
  224.  * 函数名称:
  225.  *   DIBNumColors()
  226.  *
  227.  * 参数:
  228.  *   LPSTR lpbi         - 指向DIB对象的指针
  229.  *
  230.  * 返回值:
  231.  *   WORD               - 返回调色板中颜色的种数
  232.  *
  233.  * 说明:
  234.  *   该函数返回DIB中调色板的颜色的种数。对于单色位图,返回2,
  235.  * 对于16色位图,返回16,对于256色位图,返回256;对于真彩色
  236.  * 位图(24位),没有调色板,返回0。
  237.  *
  238.  ************************************************************************/
  239. WORD WINAPI DIBNumColors(LPSTR lpbi)
  240. {
  241. WORD wBitCount;
  242. // 对于Windows的DIB, 实际颜色的数目可以比象素的位数要少。
  243. // 对于这种情况,则返回一个近似的数值。
  244. // 判断是否是WIN3.0 DIB
  245. if (IS_WIN30_DIB(lpbi))
  246. {
  247. DWORD dwClrUsed;
  248. // 读取dwClrUsed值
  249. dwClrUsed = ((LPBITMAPINFOHEADER)lpbi)->biClrUsed;
  250. if (dwClrUsed != 0)
  251. {
  252. // 如果dwClrUsed(实际用到的颜色数)不为0,直接返回该值
  253. return (WORD)dwClrUsed;
  254. }
  255. }
  256. // 读取象素的位数
  257. if (IS_WIN30_DIB(lpbi))
  258. {
  259. // 读取biBitCount值
  260. wBitCount = ((LPBITMAPINFOHEADER)lpbi)->biBitCount;
  261. }
  262. else
  263. {
  264. // 读取biBitCount值
  265. wBitCount = ((LPBITMAPCOREHEADER)lpbi)->bcBitCount;
  266. }
  267. // 按照象素的位数计算颜色数目
  268. switch (wBitCount)
  269. {
  270. case 1:
  271. return 2;
  272. case 4:
  273. return 16;
  274. case 8:
  275. return 256;
  276. default:
  277. return 0;
  278. }
  279. }
  280. /*************************************************************************
  281.  *
  282.  * 函数名称:
  283.  *   DIBBitCount()
  284.  *
  285.  * 参数:
  286.  *   LPSTR lpbi         - 指向DIB对象的指针
  287.  *
  288.  * 返回值:
  289.  *   WORD               - 返回调色板中颜色的种数
  290.  *
  291.  * 说明:
  292.  *   该函数返回DIBBitCount。
  293.  *
  294.  ************************************************************************/
  295. WORD WINAPI DIBBitCount(LPSTR lpbi)
  296. {
  297. WORD wBitCount;
  298. // 读取象素的位数
  299. if (IS_WIN30_DIB(lpbi))
  300. {
  301. // 读取biBitCount值
  302. wBitCount = ((LPBITMAPINFOHEADER)lpbi)->biBitCount;
  303. }
  304. else
  305. {
  306. // 读取biBitCount值
  307. wBitCount = ((LPBITMAPCOREHEADER)lpbi)->bcBitCount;
  308. }
  309. // 返回wBitCount
  310. return wBitCount;
  311. }
  312. /*************************************************************************
  313.  *
  314.  * 函数名称:
  315.  *   CopyHandle()
  316.  *
  317.  * 参数:
  318.  *   HGLOBAL h          - 要复制的内存区域
  319.  *
  320.  * 返回值:
  321.  *   HGLOBAL            - 复制后的新内存区域
  322.  *
  323.  * 说明:
  324.  *   该函数复制指定的内存区域。返回复制后的新内存区域,出错时返回0。
  325.  *
  326.  ************************************************************************/
  327. HGLOBAL WINAPI CopyHandle (HGLOBAL h)
  328. {
  329. if (h == NULL)
  330. return NULL;
  331. // 获取指定内存区域大小
  332. DWORD dwLen = ::GlobalSize((HGLOBAL) h);
  333. // 分配新内存空间
  334. HGLOBAL hCopy = ::GlobalAlloc(GHND, dwLen);
  335. // 判断分配是否成功
  336. if (hCopy != NULL)
  337. {
  338. // 锁定
  339. void* lpCopy = ::GlobalLock((HGLOBAL) hCopy);
  340. void* lp     = ::GlobalLock((HGLOBAL) h);
  341. // 复制
  342. memcpy(lpCopy, lp, dwLen);
  343. // 解除锁定
  344. ::GlobalUnlock(hCopy);
  345. ::GlobalUnlock(h);
  346. }
  347. return hCopy;
  348. }
  349. /*************************************************************************
  350.  *
  351.  * 函数名称:
  352.  *   SaveDIB()
  353.  *
  354.  * 参数:
  355.  *   HDIB hDib          - 要保存的DIB
  356.  *   CFile& file        - 保存文件CFile
  357.  *
  358.  * 返回值:
  359.  *   BOOL               - 成功返回TRUE,否则返回FALSE或者CFileException
  360.  *
  361.  * 说明:
  362.  *   该函数将指定的DIB对象保存到指定的CFile中。该CFile由调用程序打开和关闭。
  363.  *
  364.  *************************************************************************/
  365. BOOL WINAPI SaveDIB(HDIB hDib, CFile& file)
  366. {
  367. // Bitmap文件头
  368. BITMAPFILEHEADER bmfHdr;
  369. // 指向BITMAPINFOHEADER的指针
  370. LPBITMAPINFOHEADER lpBI;
  371. // DIB大小
  372. DWORD dwDIBSize;
  373. if (hDib == NULL)
  374. {
  375. // 如果DIB为空,返回FALSE
  376. return FALSE;
  377. }
  378. // 读取BITMAPINFO结构,并锁定
  379. lpBI = (LPBITMAPINFOHEADER) ::GlobalLock((HGLOBAL) hDib);
  380. if (lpBI == NULL)
  381. {
  382. // 为空,返回FALSE
  383. return FALSE;
  384. }
  385. // 判断是否是WIN3.0 DIB
  386. if (!IS_WIN30_DIB(lpBI))
  387. {
  388. // 不支持其它类型的DIB保存
  389. // 解除锁定
  390. ::GlobalUnlock((HGLOBAL) hDib);
  391. // 返回FALSE
  392. return FALSE;
  393. }
  394. // 填充文件头
  395. // 文件类型"BM"
  396. bmfHdr.bfType = DIB_HEADER_MARKER;
  397. // 计算DIB大小时,最简单的方法是调用GlobalSize()函数。但是全局内存大小并
  398. // 不是DIB真正的大小,它总是多几个字节。这样就需要计算一下DIB的真实大小。
  399. // 文件头大小+颜色表大小
  400. // (BITMAPINFOHEADER和BITMAPCOREHEADER结构的第一个DWORD都是该结构的大小)
  401. dwDIBSize = *(LPDWORD)lpBI + ::PaletteSize((LPSTR)lpBI);
  402. // 计算图像大小
  403. if ((lpBI->biCompression == BI_RLE8) || (lpBI->biCompression == BI_RLE4))
  404. {
  405. // 对于RLE位图,没法计算大小,只能信任biSizeImage内的值
  406. dwDIBSize += lpBI->biSizeImage;
  407. }
  408. else
  409. {
  410. // 象素的大小
  411. DWORD dwBmBitsSize;
  412. // 大小为Width * Height
  413. dwBmBitsSize = WIDTHBYTES((lpBI->biWidth)*((DWORD)lpBI->biBitCount)) * lpBI->biHeight;
  414. // 计算出DIB真正的大小
  415. dwDIBSize += dwBmBitsSize;
  416. // 更新biSizeImage(很多BMP文件头中biSizeImage的值是错误的)
  417. lpBI->biSizeImage = dwBmBitsSize;
  418. }
  419. // 计算文件大小:DIB大小+BITMAPFILEHEADER结构大小
  420. bmfHdr.bfSize = dwDIBSize + sizeof(BITMAPFILEHEADER);
  421. // 两个保留字
  422. bmfHdr.bfReserved1 = 0;
  423. bmfHdr.bfReserved2 = 0;
  424. // 计算偏移量bfOffBits,它的大小为Bitmap文件头大小+DIB头大小+颜色表大小
  425. bmfHdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + lpBI->biSize
  426.   + PaletteSize((LPSTR)lpBI);
  427. // 尝试写文件
  428. TRY
  429. {
  430. // 写文件头
  431. file.Write((LPSTR)&bmfHdr, sizeof(BITMAPFILEHEADER));
  432. // 写DIB头和象素
  433. file.WriteHuge(lpBI, dwDIBSize);
  434. }
  435. CATCH (CFileException, e)
  436. {
  437. // 解除锁定
  438. ::GlobalUnlock((HGLOBAL) hDib);
  439. // 抛出异常
  440. THROW_LAST();
  441. }
  442. END_CATCH
  443. // 解除锁定
  444. ::GlobalUnlock((HGLOBAL) hDib);
  445. // 返回TRUE
  446. return TRUE;
  447. }
  448. /*************************************************************************
  449.  *
  450.  * 函数名称:
  451.  *   ReadDIBFile()
  452.  *
  453.  * 参数:
  454.  *   CFile& file        - 要读取得文件文件CFile
  455.  *
  456.  * 返回值:
  457.  *   HDIB               - 成功返回DIB的句柄,否则返回NULL。
  458.  *
  459.  * 说明:
  460.  *   该函数将指定的文件中的DIB对象读到指定的内存区域中。除BITMAPFILEHEADER
  461.  * 外的内容都将被读入内存。
  462.  *
  463.  *************************************************************************/
  464. HDIB WINAPI ReadDIBFile(CFile& file)
  465. {
  466. BITMAPFILEHEADER bmfHeader;
  467. DWORD dwBitsSize;
  468. HDIB hDIB;
  469. LPSTR pDIB;
  470. // 获取DIB(文件)长度(字节)
  471. dwBitsSize = file.GetLength();
  472. // 尝试读取DIB文件头
  473. if (file.Read((LPSTR)&bmfHeader, sizeof(bmfHeader)) != sizeof(bmfHeader))
  474. {
  475. // 大小不对,返回NULL。
  476. return NULL;
  477. }
  478. // 判断是否是DIB对象,检查头两个字节是否是"BM"
  479. if (bmfHeader.bfType != DIB_HEADER_MARKER)
  480. {
  481. // 非DIB对象,返回NULL。
  482. return NULL;
  483. }
  484. // 为DIB分配内存
  485. hDIB = (HDIB) ::GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, dwBitsSize);
  486. if (hDIB == 0)
  487. {
  488. // 内存分配失败,返回NULL。
  489. return NULL;
  490. }
  491. // 锁定
  492. pDIB = (LPSTR) ::GlobalLock((HGLOBAL) hDIB);
  493. // 读象素
  494. if (file.ReadHuge(pDIB, dwBitsSize - sizeof(BITMAPFILEHEADER)) !=
  495. dwBitsSize - sizeof(BITMAPFILEHEADER) )
  496. {
  497. // 大小不对。
  498. // 解除锁定
  499. ::GlobalUnlock((HGLOBAL) hDIB);
  500. // 释放内存
  501. ::GlobalFree((HGLOBAL) hDIB);
  502. // 返回NULL。
  503. return NULL;
  504. }
  505. // 解除锁定
  506. ::GlobalUnlock((HGLOBAL) hDIB);
  507. // 返回DIB句柄
  508. return hDIB;
  509. }
  510. /*************************************************************************
  511.  *
  512.  * 函数名称:
  513.  *   NewDIB()
  514.  *
  515.  * 参数:
  516.  *   width - 将要创建DIB的宽
  517.  *   height - 将要创建DIB的高
  518.  *   biBitCount - 将要创建DIB的位数。比如,如果要创建256色DIB,则此值为8
  519.  * 返回值:
  520.  *   HDIB           - 成功返回DIB的句柄,否则返回NULL。
  521.  *
  522.  * 说明:
  523.  *   该函数指定宽、高、颜色位数来创建一个新的DIB,并返回其句柄
  524.  *************************************************************************/
  525. /*******************************************************************
  526. *函数名称:
  527. * NewDIB()
  528. *
  529. * 参数:
  530. * width - 将要创建DIB的宽
  531. * height - 将要创建DIB的高
  532. * biBitCount - 将要创建DIB的位数。比如,如果要创建256色DIB,则此值为8
  533. *
  534. *返回值:
  535. *  HDIB           - 成功返回DIB的句柄,否则返回NULL。
  536. *
  537. *说明:
  538. *  该函数指定宽、高、颜色位数来创建一个新的DIB,并返回其句柄
  539. *
  540. ***************************************************************/
  541. HDIB WINAPI NewDIB(long width, long height,unsigned short biBitCount) 
  542. {
  543. //计算新建的DIB每行所占的字节数
  544. long dwindth = (width*biBitCount/8+3)/4*4;
  545. //新建的DIB调色板中表项的数目 
  546.  WORD color_num;
  547.    
  548.      //通过输入的biBitCount值来确定调色板的表项数目 
  549. switch(biBitCount)
  550. {   
  551.        //如果用1 bit来表示一个象素那么调色板中有两个表项 
  552. case 1:
  553.          color_num=2;
  554. break;
  555.        //如果用4 bit来表示一个象素那么调色板中有16个表项
  556. case 4:
  557. color_num=16;
  558. break;
  559.        //如果用8bit来表示一个象素,那么调色板中得表项有256中(本程序大多采用这种形式)
  560. case 8:
  561. color_num=256;
  562. break;
  563.        //其他的情况调色扳中没有表项,即真彩位图
  564. default:
  565. color_num=0;
  566. break;
  567. }
  568. //计算位图数据所占的空间
  569. //dwindth *height为象素数据所占的空间
  570. //40为位图信息头占的空间
  571. //color_num*4为调色板的表项所占的空间(调色板每个表项占4各个字节)
  572.  long   dwBitsSize = dwindth *height + 40 + color_num*4;
  573. //建立指向位图文件的指针 
  574. LPSTR pDIB;
  575. //申请存储空间,并建立指向位图的句柄
  576. HDIB hDIB=(HDIB) ::GlobalAlloc(GMEM_MOVEABLE|GMEM_ZEROINIT, dwBitsSize);
  577. //如果申请空间不成功返回错误信息
  578. if (hDIB == 0)
  579. {
  580. return NULL;
  581. }
  582.    //如果申请空间成功锁定内存,并将内存的指针传给pDIB
  583. pDIB = (LPSTR) ::GlobalLock((HGLOBAL) hDIB);
  584.    //建立指向位图信息头结构的指针
  585. LPBITMAPINFO lpmf = (LPBITMAPINFO)pDIB;
  586.    //给位图信息头内的各个参量赋值
  587.    //指定位图信息头结构的大小为40字节
  588. lpmf->bmiHeader.biSize = 40;
  589.    //指定新建位图的宽度
  590. lpmf->bmiHeader.biWidth = width;
  591.    //指定新建位图的高度
  592. lpmf->bmiHeader.biHeight = height;
  593.    //位平面数必须为1
  594. lpmf->bmiHeader.biPlanes = 1;
  595. //确定新建位图表示颜色是要用到的bit数
  596. lpmf->bmiHeader.biBitCount = biBitCount;
  597.     //是否进行压缩
  598. lpmf->bmiHeader.biCompression = 0;
  599.     //新建的位图中实际的位图数据所占的字节数
  600. lpmf->bmiHeader.biSizeImage = dwindth *height;
  601. //指定目标设备的水平分辨率
  602. lpmf->bmiHeader.biXPelsPerMeter = 2925;
  603.     //指定目标设备的垂直分辨率
  604. lpmf->bmiHeader.biYPelsPerMeter = 2925;
  605. //新建图像实际用到的颜色数 如果为0则用到的颜色数为2的biBitCount次
  606. lpmf->bmiHeader.biClrUsed = 0;
  607.  
  608. //指定新建图像中重要的颜色数,如果为0则所有的颜色都重要
  609. lpmf->bmiHeader.biClrImportant= 0; 
  610.     
  611.     //如果新建的图像中含有调色板,则接下来对调色板的各种颜色分量赋初始值
  612. if(color_num!=0)
  613. {
  614. for(int i=0;i<color_num;i++)
  615. {
  616. lpmf->bmiColors[i].rgbRed =(BYTE)i;
  617. lpmf->bmiColors[i].rgbGreen =(BYTE)i;
  618. lpmf->bmiColors[i].rgbBlue =(BYTE)i;
  619. }
  620. }
  621. //解除锁定
  622. ::GlobalUnlock((HGLOBAL) hDIB);
  623. //返回新建位图的句柄
  624.  return hDIB;
  625. }
  626. /*************************************************************************
  627.  *
  628.  * 函数名称:
  629.  *   PaletteSize()
  630.  *
  631.  * 参数:
  632.  *   LPSTR lpbi         - 指向DIB对象的指针
  633.  *
  634.  * 返回值:
  635.  *   WORD               - DIB中调色板的大小
  636.  *
  637.  * 说明:
  638.  *   该函数返回DIB中调色板的大小。对于Windows 3.0 DIB,返回颜色数目×
  639.  * RGBQUAD的大小;对于其它返回颜色数目×RGBTRIPLE的大小。
  640.  *
  641.  ************************************************************************/
  642. WORD WINAPI PaletteSize(LPSTR lpbi)
  643. {
  644. // 计算DIB中调色板的大小
  645. if (IS_WIN30_DIB (lpbi))
  646. {
  647. //返回颜色数目×RGBQUAD的大小
  648. return (WORD)(::DIBNumColors(lpbi) * sizeof(RGBQUAD));
  649. }
  650. else
  651. {
  652. //返回颜色数目×RGBTRIPLE的大小
  653. return (WORD)(::DIBNumColors(lpbi) * sizeof(RGBTRIPLE));
  654. }
  655. }