分享

DibImage.cpp

 学海无涯GL 2012-09-19
  1. http://read./downloads112/sourcecode/graph/466338/DIBDisplay/DibImage.cpp__.htm

    1. // DibImage.cpp: implementation of the CDibImage class.    
    2. //  DIB(Independent Bitmap) 函数:    
    3. //    
    4. //  PaintDIB()          - 绘制DIB对象    
    5. //  CreateDIBPalette()  - 创建DIB对象调色板    
    6. //  FindDIBBits()       - 返回DIB图像象素起始位置    
    7. //  DIBWidth()          - 返回DIB宽度    
    8. //  DIBHeight()         - 返回DIB高度    
    9. //  PaletteSize()       - 返回DIB调色板大小    
    10. //  DIBNumColors()      - 计算DIB调色板颜色数目    
    11. //  CopyHandle()        - 拷贝内存块    
    12. //    
    13. //  SaveDIB()           - 将DIB保存到指定文件中    
    14. //  ReadDIBFile()       - 重指定文件中读取DIB对象    
    15. //////////////////////////////////////////////////////////////////////    
    16.    
    17. #include "stdafx.h"    
    18. #include "DIBDisplay.h"    
    19. #include "DibImage.h"    
    20.    
    21. #ifdef _DEBUG    
    22. #undef THIS_FILE    
    23. static char THIS_FILE[]=__FILE__;   
    24. #define new DEBUG_NEW    
    25. #endif    
    26.    
    27. //////////////////////////////////////////////////////////////////////    
    28. // Construction/Destruction    
    29. //////////////////////////////////////////////////////////////////////    
    30.    
    31. CDibImage::CDibImage()   
    32. {   
    33.    
    34. }   
    35.    
    36. CDibImage::~CDibImage()   
    37. {   
    38.    
    39. }   
    40.    
    41. //////////////////////////////////////////////////////////////////////    
    42. // function     
    43. //////////////////////////////////////////////////////////////////////    
    44.    
    45. /*************************************************************************  
    46.  * 函数名称:  
    47.  *   PaintDIB()  
    48.  * 参数:  
    49.  *   HDC hDC            - 输出设备DC  
    50.  *   LPRECT lpDCRect    - 绘制矩形区域  
    51.  *   HDIB hDIB          - 指向DIB对象的指针  
    52.  *   LPRECT lpDIBRect   - 要输出的DIB区域  
    53.  *   CPalette* pPal     - 指向DIB对象调色板的指针  
    54.  * 返回值:  
    55.  *   BOOL               - 绘制成功返回TRUE,否则返回FALSE。  
    56.  * 说明:  
    57.  *   该函数主要用来绘制DIB对象。其中调用了StretchDIBits()或者  
    58.  * SetDIBitsToDevice()来绘制DIB对象。输出的设备由由参数hDC指  
    59.  * 定;绘制的矩形区域由参数lpDCRect指定;输出DIB的区域由参数  
    60.  * lpDIBRect指定。  
    61.  ************************************************************************/   
    62. BOOL CDibImage::PaintDIB(HDC     hDC,   
    63.                     LPRECT  lpDCRect,   
    64.                     HDIB    hDIB,   
    65.                     LPRECT  lpDIBRect,   
    66.                     CPalette* pPal)   
    67. {   
    68.     LPSTR    lpDIBHdr;            // BITMAPINFOHEADER指针    
    69.     LPSTR    lpDIBBits;           // DIB象素指针    
    70.     BOOL     bSuccess=FALSE;      // 成功标志    
    71.     HPALETTE hPal=NULL;           // DIB调色板    
    72.     HPALETTE hOldPal=NULL;        // 以前的调色板    
    73.    
    74.     if (hDIB == NULL)   
    75.     {   
    76.         return FALSE;   
    77.     }   
    78.        
    79.     lpDIBHdr  = (LPSTR)::GlobalLock((HGLOBAL) hDIB);// 锁定DIB        
    80.     lpDIBBits = FindDIBBits(lpDIBHdr);  // 找到DIB图像象素起始位置    
    81.    
    82.     if (pPal != NULL)                   // 获取DIB调色板,并选中它    
    83.     {   
    84.         hPal = (HPALETTE) pPal->m_hObject;      
    85.         hOldPal = ::SelectPalette(hDC, hPal, TRUE); // 选中调色板    
    86.     }   
    87.    
    88.     ::SetStretchBltMode(hDC, COLORONCOLOR);         // 设置显示模式    
    89.    
    90.     // 判断是调用StretchDIBits()还是SetDIBitsToDevice()来绘制DIB对象    
    91.     if ((RECTWIDTH(lpDCRect)  == RECTWIDTH(lpDIBRect)) &&   
    92.        (RECTHEIGHT(lpDCRect) == RECTHEIGHT(lpDIBRect)))   
    93.     {   
    94.         // 原始大小,不用拉伸。    
    95.         bSuccess = ::SetDIBitsToDevice(hDC,                    // hDC    
    96.                                    lpDCRect->left,             // DestX    
    97.                                    lpDCRect->top,              // DestY    
    98.                                    RECTWIDTH(lpDCRect),        // nDestWidth    
    99.                                    RECTHEIGHT(lpDCRect),       // nDestHeight    
    100.                                    lpDIBRect->left,            // SrcX    
    101.                                    (int)DIBHeight(lpDIBHdr) -   
    102.                                       lpDIBRect->top -   
    103.                                       RECTHEIGHT(lpDIBRect),   // SrcY    
    104.                                    0,                          // nStartScan    
    105.                                    (WORD)DIBHeight(lpDIBHdr),  // nNumScans    
    106.                                    lpDIBBits,                  // lpBits    
    107.                                    (LPBITMAPINFO)lpDIBHdr,     // lpBitsInfo    
    108.                                    DIB_RGB_COLORS);            // wUsage    
    109.     }   
    110.     else   
    111.     {   
    112.         // 非原始大小,拉伸。    
    113.         bSuccess = ::StretchDIBits(hDC,                          // hDC    
    114.                                lpDCRect->left,                 // DestX    
    115.                                lpDCRect->top,                  // DestY    
    116.                                RECTWIDTH(lpDCRect),            // nDestWidth    
    117.                                RECTHEIGHT(lpDCRect),           // nDestHeight    
    118.                                lpDIBRect->left,                // SrcX    
    119.                                lpDIBRect->top,                 // SrcY    
    120.                                RECTWIDTH(lpDIBRect),           // wSrcWidth    
    121.                                RECTHEIGHT(lpDIBRect),          // wSrcHeight    
    122.                                lpDIBBits,                      // lpBits    
    123.                                (LPBITMAPINFO)lpDIBHdr,         // lpBitsInfo    
    124.                                DIB_RGB_COLORS,                 // wUsage    
    125.                                SRCCOPY);                       // dwROP    
    126.     }   
    127.         
    128.     ::GlobalUnlock((HGLOBAL) hDIB);             // 解除锁定     
    129.     if (hOldPal != NULL)   
    130.     {   
    131.         ::SelectPalette(hDC, hOldPal, TRUE);    // 恢复以前的调色板    
    132.     }      
    133.     return bSuccess;   
    134. }   
    135.    
    136. /*************************************************************************  
    137.  * 函数名称:  
    138.  *   CreateDIBPalette()  
    139.  * 参数:  
    140.  *   HDIB hDIB          - 指向DIB对象的指针  
    141.  *   CPalette* pPal     - 指向DIB对象调色板的指针  
    142.  * 返回值:  
    143.  *   BOOL               - 创建成功返回TRUE,否则返回FALSE。  
    144.  * 说明:  
    145.  *   该函数按照DIB创建一个逻辑调色板,从DIB中读取颜色表并存到调色板中,  
    146.  * 最后按照该逻辑调色板创建一个新的调色板,并返回该调色板的句柄。这样  
    147.  * 可以用最好的颜色来显示DIB图像。  
    148.  ************************************************************************/   
    149. BOOL CDibImage::CreateDIBPalette(HDIB hDIB, CPalette* pPal)   
    150. {   
    151.        
    152.     LPLOGPALETTE lpPal;     // 指向逻辑调色板的指针    
    153.     HANDLE hLogPal;         // 逻辑调色板的句柄    
    154.     HPALETTE hPal = NULL;   // 调色板的句柄    
    155.     int i;                  // 循环变量     
    156.     WORD wNumColors;        // 颜色表中的颜色数目        
    157.     LPSTR lpbi;             // 指向DIB的指针     
    158.     LPBITMAPINFO lpbmi;     // 指向BITMAPINFO结构的指针(Win3.0)        
    159.     LPBITMAPCOREINFO lpbmc; // 指向BITMAPCOREINFO结构的指针        
    160.     BOOL bWinStyleDIB;      // 表明是否是Win3.0 DIB的标记       
    161.     BOOL bResult = FALSE;   // 创建结果    
    162.        
    163.     if (hDIB == NULL)   
    164.     {   
    165.         return FALSE;   
    166.     }   
    167.            
    168.     lpbi = (LPSTR) ::GlobalLock((HGLOBAL) hDIB);    // 锁定DIB    
    169.     lpbmi = (LPBITMAPINFO)lpbi;     // 获取指向BITMAPINFO结构的指针(Win3.0)    
    170.     lpbmc = (LPBITMAPCOREINFO)lpbi; // 获取指向BITMAPCOREINFO结构的指针    
    171.     wNumColors = DIBNumColors(lpbi);// 获取DIB中颜色表中的颜色数目    
    172.        
    173.     if (wNumColors != 0)   
    174.     {   
    175.         // 分配为逻辑调色板内存    
    176.         hLogPal = ::GlobalAlloc(GHND, sizeof(LOGPALETTE)   
    177.                                     + sizeof(PALETTEENTRY)   
    178.                                     * wNumColors);     
    179.         // 如果内存不足,退出    
    180.         if (hLogPal == 0)   
    181.         {      
    182.             ::GlobalUnlock((HGLOBAL) hDIB); // 解除锁定    
    183.             return FALSE;   
    184.         }   
    185.            
    186.         lpPal = (LPLOGPALETTE) ::GlobalLock((HGLOBAL) hLogPal);        
    187.         lpPal->palVersion = PALVERSION;          // 设置版本号    
    188.         lpPal->palNumEntries = (WORD)wNumColors;// 设置颜色数目    
    189.         bWinStyleDIB = IS_WIN30_DIB(lpbi);      // 判断是否是WIN3.0的DIB    
    190.    
    191.         // 读取调色板    
    192.         for (i = 0; i < (int)wNumColors; i++)   
    193.         {   
    194.             if (bWinStyleDIB)   
    195.             {   
    196.                 // 读取红色绿色蓝色分量    
    197.                 lpPal->palPalEntry[i].peRed = lpbmi->bmiColors[i].rgbRed;   
    198.                 lpPal->palPalEntry[i].peGreen = lpbmi->bmiColors[i].rgbGreen;   
    199.                 lpPal->palPalEntry[i].peBlue = lpbmi->bmiColors[i].rgbBlue;                  
    200.                 // 保留位    
    201.                 lpPal->palPalEntry[i].peFlags = 0;   
    202.             }   
    203.             else   
    204.             {   
    205.                 // 读取红色绿色蓝色分量    
    206.                 lpPal->palPalEntry[i].peRed = lpbmc->bmciColors[i].rgbtRed;   
    207.                 lpPal->palPalEntry[i].peGreen = lpbmc->bmciColors[i].rgbtGreen;   
    208.                 lpPal->palPalEntry[i].peBlue = lpbmc->bmciColors[i].rgbtBlue;                
    209.                 // 保留位    
    210.                 lpPal->palPalEntry[i].peFlags = 0;   
    211.             }   
    212.         }   
    213.                
    214.         bResult = pPal->CreatePalette(lpPal);// 按照逻辑调色板创建调色板,并返回指针    
    215.         ::GlobalUnlock((HGLOBAL) hLogPal);  // 解除锁定    
    216.         ::GlobalFree((HGLOBAL) hLogPal);    // 释放逻辑调色板    
    217.     }   
    218.        
    219.     ::GlobalUnlock((HGLOBAL) hDIB);         // 解除锁定    
    220.     return bResult;   
    221. }   
    222.    
    223. /*************************************************************************  
    224.  * 函数名称:  
    225.  *   FindDIBBits()  
    226.  * 参数:  
    227.  *   LPSTR lpbi         - 指向DIB对象的指针  
    228.  * 返回值:  
    229.  *   LPSTR              - 指向DIB图像象素起始位置  
    230.  * 说明:  
    231.  *   该函数计算DIB中图像象素的起始位置,并返回指向它的指针。  
    232.  ************************************************************************/   
    233. LPSTR CDibImage::FindDIBBits(LPSTR lpbi)   
    234. {   
    235.     return (lpbi + *(LPDWORD)lpbi + PaletteSize(lpbi));   
    236. }   
    237.    
    238. /*************************************************************************  
    239.  * 函数名称:  
    240.  *   DIBWidth()  
    241.  * 参数:  
    242.  *   LPSTR lpbi         - 指向DIB对象的指针  
    243.  * 返回值:  
    244.  *   DWORD              - DIB中图像的宽度  
    245.  * 说明:  
    246.  *   该函数返回DIB中图像的宽度。对于Windows 3.0 DIB,返回BITMAPINFOHEADER  
    247.  * 中的biWidth值;对于其它返回BITMAPCOREHEADER中的bcWidth值。  
    248.  ************************************************************************/   
    249. DWORD CDibImage::DIBWidth(LPSTR lpDIB)   
    250. {   
    251.     LPBITMAPINFOHEADER lpbmi;   // 指向BITMAPINFO结构的指针(Win3.0)    
    252.     LPBITMAPCOREHEADER lpbmc;   // 指向BITMAPCOREINFO结构的指针    
    253.     lpbmi = (LPBITMAPINFOHEADER)lpDIB;   
    254.     lpbmc = (LPBITMAPCOREHEADER)lpDIB;   
    255.    
    256.     // 返回DIB中图像的宽度    
    257.     if (IS_WIN30_DIB(lpDIB))   
    258.     {          
    259.         return lpbmi->biWidth;       // 对于Windows 3.0 DIB,返回lpbmi->biWidth    
    260.     }   
    261.     else   
    262.     {          
    263.         return (DWORD)lpbmc->bcWidth;    // 对于其它格式的DIB,返回lpbmc->bcWidth    
    264.     }   
    265. }   
    266.    
    267. /*************************************************************************  
    268.  * 函数名称:  
    269.  *   DIBHeight()  
    270.  * 参数:  
    271.  *   LPSTR lpDIB        - 指向DIB对象的指针  
    272.  * 返回值:  
    273.  *   DWORD              - DIB中图像的高度  
    274.  * 说明:  
    275.  *   该函数返回DIB中图像的高度。对于Windows 3.0 DIB,返回BITMAPINFOHEADER  
    276.  * 中的biHeight值;对于其它返回BITMAPCOREHEADER中的bcHeight值。  
    277.  ************************************************************************/   
    278. DWORD CDibImage::DIBHeight(LPSTR lpDIB)   
    279. {      
    280.     LPBITMAPINFOHEADER lpbmi;   // 指向BITMAPINFO结构的指针(Win3.0)    
    281.     LPBITMAPCOREHEADER lpbmc;   // 指向BITMAPCOREINFO结构的指针    
    282.     lpbmi = (LPBITMAPINFOHEADER)lpDIB;   
    283.     lpbmc = (LPBITMAPCOREHEADER)lpDIB;   
    284.    
    285.     // 返回DIB中图像的宽度    
    286.     if (IS_WIN30_DIB(lpDIB))   
    287.     {          
    288.         return lpbmi->biHeight;      // 对于Windows 3.0 DIB,返回lpbmi->biHeight    
    289.     }   
    290.     else   
    291.     {          
    292.         return (DWORD)lpbmc->bcHeight;   // 对于其它格式的DIB,返回lpbmc->bcHeight    
    293.     }   
    294. }   
    295.    
    296. /*************************************************************************  
    297.  * 函数名称:  
    298.  *   PaletteSize()  
    299.  * 参数:  
    300.  *   LPSTR lpbi         - 指向DIB对象的指针  
    301.  * 返回值:  
    302.  *   WORD               - DIB中调色板的大小  
    303.  * 说明:  
    304.  *   该函数返回DIB中调色板的大小。对于Windows 3.0 DIB,返回颜色数目×  
    305.  * RGBQUAD的大小;对于其它返回颜色数目×RGBTRIPLE的大小。  
    306.  ************************************************************************/   
    307. WORD CDibImage::PaletteSize(LPSTR lpbi)   
    308. {   
    309.     // 计算DIB中调色板的大小    
    310.     if (IS_WIN30_DIB (lpbi))   
    311.     {   
    312.         //返回颜色数目×RGBQUAD的大小    
    313.         return (WORD)(DIBNumColors(lpbi) * sizeof(RGBQUAD));   
    314.     }   
    315.     else   
    316.     {   
    317.         //返回颜色数目×RGBTRIPLE的大小    
    318.         return (WORD)(DIBNumColors(lpbi) * sizeof(RGBTRIPLE));   
    319.     }   
    320. }   
    321.    
    322. /*************************************************************************  
    323.  * 函数名称:  
    324.  *   DIBNumColors()  
    325.  * 参数:  
    326.  *   LPSTR lpbi         - 指向DIB对象的指针  
    327.  * 返回值:  
    328.  *   WORD               - 返回调色板中颜色的种数  
    329.  * 说明:  
    330.  *   该函数返回DIB中调色板的颜色的种数。对于单色位图,返回2,  
    331.  * 对于16色位图,返回16,对于256色位图,返回256;对于真彩色  
    332.  * 位图(24位),没有调色板,返回0。  
    333.  ************************************************************************/   
    334. WORD CDibImage::DIBNumColors(LPSTR lpbi)   
    335. {   
    336.     WORD wBitCount;   
    337.    
    338.     // 对于Windows的DIB, 实际颜色的数目可以比象素的位数要少。    
    339.     // 对于这种情况,则返回一个近似的数值。    
    340.        
    341.     // 判断是否是WIN3.0 DIB    
    342.     if (IS_WIN30_DIB(lpbi))   
    343.     {   
    344.         DWORD dwClrUsed;   
    345.         dwClrUsed = ((LPBITMAPINFOHEADER)lpbi)->biClrUsed;   // 读取dwClrUsed值    
    346.            
    347.         if (dwClrUsed != 0)   
    348.         {   
    349.             // 如果dwClrUsed(实际用到的颜色数)不为0,直接返回该值    
    350.             return (WORD)dwClrUsed;   
    351.         }   
    352.     }   
    353.    
    354.     // 读取象素的位数    
    355.     if (IS_WIN30_DIB(lpbi))   
    356.     {          
    357.         wBitCount = ((LPBITMAPINFOHEADER)lpbi)->biBitCount;  // 读取biBitCount值    
    358.     }   
    359.     else   
    360.     {          
    361.         wBitCount = ((LPBITMAPCOREHEADER)lpbi)->bcBitCount;  // 读取biBitCount值    
    362.     }   
    363.        
    364.     // 按照象素的位数计算颜色数目    
    365.     switch (wBitCount)   
    366.     {   
    367.         case 1:   
    368.             return 2;   
    369.             break;   
    370.         case 4:   
    371.             return 16;   
    372.             break;   
    373.         case 8:   
    374.             return 256;   
    375.             break;   
    376.         default:   
    377.             return 0;   
    378.             break;   
    379.     }   
    380. }   
    381.    
    382. /*************************************************************************  
    383.  * 函数名称:  
    384.  *   CopyHandle()  
    385.  * 参数:  
    386.  *   HGLOBAL h          - 要复制的内存区域  
    387.  * 返回值:  
    388.  *   HGLOBAL            - 复制后的新内存区域  
    389.  * 说明:  
    390.  *   该函数复制指定的内存区域。返回复制后的新内存区域,出错时返回0。  
    391.  ************************************************************************/   
    392. HGLOBAL CDibImage::CopyHandle (HGLOBAL h)   
    393. {   
    394.     if (h == NULL)   
    395.     {   
    396.         return NULL;   
    397.     }   
    398.        
    399.     DWORD dwLen = ::GlobalSize((HGLOBAL) h);    // 获取指定内存区域大小    
    400.     HGLOBAL hCopy = ::GlobalAlloc(GHND, dwLen); // 分配新内存空间      
    401.     if (hCopy != NULL)                          // 判断分配是否成功    
    402.     {   
    403.         void* lpCopy = ::GlobalLock((HGLOBAL) hCopy);   
    404.         void* lp     = ::GlobalLock((HGLOBAL) h);   
    405.            
    406.         memcpy(lpCopy, lp, dwLen);   
    407.            
    408.         ::GlobalUnlock(hCopy);   
    409.         ::GlobalUnlock(h);   
    410.     }   
    411.    
    412.     return hCopy;   
    413. }   
    414.    
    415. /*************************************************************************  
    416.  * 函数名称:  
    417.  *   SaveDIB()  
    418.  * 参数:  
    419.  *   HDIB hDib          - 要保存的DIB  
    420.  *   CFile& file        - 保存文件CFile  
    421.  * 返回值:  
    422.  *   BOOL               - 成功返回TRUE,否则返回FALSE或者CFileException  
    423.  * 说明:  
    424.  *   该函数将指定的DIB对象保存到指定的CFile中。该CFile由调用程序打开和关闭。  
    425.  *************************************************************************/   
    426. BOOL CDibImage::SaveDIB(HDIB hDib, CFile& file)   
    427. {      
    428.     BITMAPFILEHEADER bmfHdr;    // Bitmap文件头        
    429.     LPBITMAPINFOHEADER lpBI;    // 指向BITMAPINFOHEADER的指针    
    430.     DWORD dwDIBSize;            // DIB大小    
    431.    
    432.     if (hDib == NULL)   
    433.     {   
    434.         return FALSE;   
    435.     }   
    436.    
    437.     // 读取BITMAPINFO结构,并锁定    
    438.     lpBI = (LPBITMAPINFOHEADER) ::GlobalLock((HGLOBAL) hDib);      
    439.     if (lpBI == NULL)   
    440.     {   
    441.         return FALSE;   
    442.     }   
    443.        
    444.     // 判断是否是WIN3.0 DIB    
    445.     if (!IS_WIN30_DIB(lpBI))   
    446.     {   
    447.         // 不支持其它类型的DIB保存    
    448.         ::GlobalUnlock((HGLOBAL) hDib);   
    449.         return FALSE;   
    450.     }   
    451.    
    452.     ////////////////////////////////////////////////////////////////////////    
    453.     // 填充文件头///////////////////////////////////////////////////////////     
    454.     bmfHdr.bfType = DIB_HEADER_MARKER;      // 文件类型"BM"    
    455.    
    456.     // 计算DIB大小时,最简单的方法是调用GlobalSize()函数。但是全局内存大小并    
    457.     // 不是DIB真正的大小,它总是多几个字节。这样就需要计算一下DIB的真实大小。    
    458.        
    459.     // 文件头大小+颜色表大小    
    460.     // (BITMAPINFOHEADER和BITMAPCOREHEADER结构的第一个DWORD都是该结构的大小)    
    461.     dwDIBSize = *(LPDWORD)lpBI + PaletteSize((LPSTR)lpBI);   
    462.        
    463.     // 计算图像大小    
    464.     if ((lpBI->biCompression == BI_RLE8) || (lpBI->biCompression == BI_RLE4))   
    465.     {   
    466.         // 对于RLE位图,没法计算大小,只能信任biSizeImage内的值    
    467.         dwDIBSize += lpBI->biSizeImage;   
    468.     }   
    469.     else   
    470.     {          
    471.         DWORD dwBmBitsSize;         // 象素的大小    
    472.         dwBmBitsSize = WIDTHBYTES((lpBI->biWidth)*((DWORD)lpBI->biBitCount))    
    473.             * lpBI->biHeight;        // 大小为Width * Height    
    474.         dwDIBSize += dwBmBitsSize;  // 计算出DIB真正的大小    
    475.    
    476.         // 更新biSizeImage(很多BMP文件头中biSizeImage的值是错误的)    
    477.         lpBI->biSizeImage = dwBmBitsSize;   
    478.     }   
    479.    
    480.     // 计算文件大小:DIB大小+BITMAPFILEHEADER结构大小    
    481.     bmfHdr.bfSize = dwDIBSize + sizeof(BITMAPFILEHEADER);   
    482.        
    483.     // 两个保留字    
    484.     bmfHdr.bfReserved1 = 0;   
    485.     bmfHdr.bfReserved2 = 0;   
    486.    
    487.     // 计算偏移量bfOffBits,它的大小为Bitmap文件头大小+DIB头大小+颜色表大小    
    488.     bmfHdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + lpBI->biSize   
    489.                                               + PaletteSize((LPSTR)lpBI);   
    490.    
    491.     /////////////////////////////////////////////////////////////////////////    
    492.     // 尝试写文件////////////////////////////////////////////////////////////    
    493.     TRY   
    494.     {          
    495.         file.Write((LPSTR)&bmfHdr, sizeof(BITMAPFILEHEADER));   // 写文件头    
    496.         file.WriteHuge(lpBI, dwDIBSize);                    // 写DIB头和象素    
    497.     }   
    498.     CATCH (CFileException, e)   
    499.     {   
    500.         ::GlobalUnlock((HGLOBAL) hDib);   
    501.         THROW_LAST();   
    502.     }   
    503.     END_CATCH   
    504.        
    505.     ::GlobalUnlock((HGLOBAL) hDib);   
    506.     return TRUE;   
    507. }   
    508.    
    509. /*************************************************************************  
    510.  * 函数名称:  
    511.  *   ReadDIBFile()  
    512.  * 参数:  
    513.  *   CFile& file        - 要读取得文件文件CFile  
    514.  * 返回值:  
    515.  *   HDIB               - 成功返回DIB的句柄,否则返回NULL。  
    516.  * 说明:  
    517.  *   该函数将指定的文件中的DIB对象读到指定的内存区域中。除BITMAPFILEHEADER  
    518.  * 外的内容都将被读入内存。  
    519.  *************************************************************************/   
    520. HDIB CDibImage::ReadDIBFile(CFile& file)   
    521. {   
    522.     BITMAPFILEHEADER bmfHeader;   
    523.     HDIB hDIB;   
    524.     LPSTR pDIB;   
    525.     DWORD dwBitsSize;   
    526.    
    527.     dwBitsSize = file.GetLength();      // 获取DIB(文件)长度(字节)    
    528.    
    529.     // 尝试读取DIB文件头    
    530.     if (file.Read((LPSTR)&bmfHeader, sizeof(bmfHeader)) != sizeof(bmfHeader))   
    531.     {   
    532.         return NULL;   
    533.     }   
    534.     // 判断是否是DIB对象,检查头两个字节是否是"BM"    
    535.     if (bmfHeader.bfType != DIB_HEADER_MARKER)   
    536.     {   
    537.         return NULL;   
    538.     }   
    539.     // 为DIB分配内存    
    540.     hDIB = (HDIB) ::GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, dwBitsSize);   
    541.     if (hDIB == 0)   
    542.     {   
    543.         return NULL;   
    544.     }   
    545.        
    546.     pDIB = (LPSTR) ::GlobalLock((HGLOBAL) hDIB);   
    547.     if (file.ReadHuge(pDIB, dwBitsSize - sizeof(BITMAPFILEHEADER)) !=   
    548.         dwBitsSize - sizeof(BITMAPFILEHEADER) )     // 读象素    
    549.     {   
    550.         ::GlobalUnlock((HGLOBAL) hDIB);   
    551.         ::GlobalFree((HGLOBAL) hDIB);   
    552.         return NULL;   
    553.     }   
    554.    
    555.     ::GlobalUnlock((HGLOBAL) hDIB);   
    556.     return hDIB;   
    557. }  

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多