win32 显示 带调色板 的BMP文件

win7 64位
创建 一个 MFC 对话框程序:
添加一个按钮:
按钮的 点击事件处理函数内容如下:

代码主要演示 函数的用法

void CBMP_SHOW_PLADlg::OnBnClickedBtnShowBmpPla()
{
    // TODO: 在此添加控件通知处理程序代码

     OPENFILENAME ofn ;
     static TCHAR        szFileName [MAX_PATH], szTitleName [MAX_PATH] ;
     static TCHAR        szFilter[] = TEXT ("Bitmap Files (*.BMP)\0*.bmp\0")
                                      TEXT ("All Files (*.*)\0*.*\0\0") ;

    TCHAR   tszTempPath[_MAX_PATH];

    HWND hWnd;
    HDC hdcWindow ;


    hWnd = AfxGetMainWnd()->m_hWnd;

    hdcWindow =::GetDC(hWnd);

    ZeroMemory(tszTempPath, MAX_PATH);

    GetCurrentDirectory(MAX_PATH, tszTempPath);

    ofn.lStructSize       = sizeof (OPENFILENAME) ;
    ofn.hwndOwner         = NULL ;
    ofn.hInstance         = NULL ;
    ofn.lpstrFilter       = szFilter ;
    ofn.lpstrCustomFilter = NULL ;
    ofn.nMaxCustFilter    = 0 ;
    ofn.nFilterIndex      = 0 ;
    ofn.lpstrFile         = szFileName ;
    ofn.nMaxFile          = MAX_PATH ;
    ofn.lpstrFileTitle    = szTitleName ;
    ofn.nMaxFileTitle     = MAX_PATH ;
    ofn.lpstrInitialDir   = tszTempPath ;
    ofn.lpstrTitle        = NULL ;
    ofn.Flags             = 0 ;
    ofn.nFileOffset       = 0 ;
    ofn.nFileExtension    = 0 ;
    ofn.lpstrDefExt       = TEXT ("bmp") ;
    ofn.lCustData         = 0 ;
    ofn.lpfnHook          = NULL ;
    ofn.lpTemplateName    = NULL ;


    BOOL bRet = GetOpenFileName (&ofn);

    if(!bRet){

        return ;

    }


    printf("szFileName = %S\r\n",szFileName);

     _tprintf(_T("%s\r\n"),szFileName);


      TCHAR     * szCompression [] = { TEXT ("BI_RGB"), TEXT ("BI_RLE8"),
                                             TEXT ("BI_RLE4"),
                                             TEXT ("BI_BITFIELDS"),
                                             TEXT ("unknown") } ;


     BITMAPCOREHEADER * pbmch ;
     BITMAPFILEHEADER * pbmfh ;

     BOOL               bSuccess ;
     DWORD              dwFileSize, dwHighSize, dwBytesRead ;
     HANDLE             hFile ;
     int                i ;
     PBYTE              pFile ;
     TCHAR            * szV ;

     BITMAPINFOHEADER  * pbmih ;
     BITMAPV4HEADER    *pbmihv4 ;
     BITMAPV5HEADER    *pbmihv5 ;


     hFile = CreateFile (szFileName, GENERIC_READ, FILE_SHARE_READ, NULL,
                         OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL) ;

     if (hFile == INVALID_HANDLE_VALUE)
     {
          printf("Cannot open file.\r\n\r\n") ;
          return ;
     }

          // Get the size of the file

     dwFileSize = GetFileSize (hFile, &dwHighSize) ;

     if (dwHighSize)
     {
          printf("Cannot deal with >4G files.\r\n\r\n") ;
          CloseHandle (hFile) ;
          return ;
     }

     // Allocate memory for the file

     pFile = (PBYTE )malloc (dwFileSize) ;

     if (!pFile)
     {
          printf("Cannot allocate memory.\r\n\r\n") ;
          CloseHandle (hFile) ;
          return ;
     }

     bSuccess = ReadFile (hFile, pFile, dwFileSize, &dwBytesRead, NULL) ;

     if (!bSuccess || (dwBytesRead != dwFileSize))
     {
          printf("Could not read file.\r\n\r\n") ;
          CloseHandle (hFile) ;
          free (pFile) ;
          return ;
     }

     CloseHandle (hFile) ;



     printf("File size = %u bytes\r\n\r\n", dwFileSize) ;

          // Display BITMAPFILEHEADER structure

     pbmfh = (BITMAPFILEHEADER *) pFile ;

     printf("BITMAPFILEHEADER\r\n") ;
     printf("\t.bfType = 0x%X\r\n", pbmfh->bfType) ;
     printf("\t.bfSize = %u\r\n", pbmfh->bfSize) ;
     printf("\t.bfReserved1 = %u\r\n", pbmfh->bfReserved1) ;
     printf("\t.bfReserved2 = %u\r\n", pbmfh->bfReserved2) ;
     printf("\t.bfOffBits = %u\r\n\r\n", pbmfh->bfOffBits) ;



        // Determine which information structure we have

     DWORD InfoHeadSize = *((DWORD *)(pFile +sizeof (BITMAPFILEHEADER)));

     printf("InfoHeadSize = %d\n",InfoHeadSize);

    pbmih = (BITMAPINFOHEADER *) (pFile + sizeof (BITMAPFILEHEADER)) ;

    szV = TEXT ("i");
    printf("\t.b%sSize = %u\r\n", szV, pbmih->biSize) ;
    printf("\t.b%sWidth = %i\r\n", szV, pbmih->biWidth);
    printf("\t.b%sHeight = %i\r\n", szV, pbmih->biHeight) ;
    printf("\t.b%sPlanes = %u\r\n", szV, pbmih->biPlanes) ;
    printf("\t.b%sBitCount = %u\r\n", szV, pbmih->biBitCount) ;
    printf("\t.b%sCompression = %S\r\n", szV, 
                szCompression [min (4, pbmih->biCompression)]) ;

    printf("\t.b%sSizeImage = %u\r\n", szV, pbmih->biSizeImage);
    printf("\t.b%sXPelsPerMeter = %i\r\n", szV, 
                pbmih->biXPelsPerMeter) ;
    printf("\t.b%sYPelsPerMeter = %i\r\n", szV, 
                pbmih->biYPelsPerMeter) ;
    printf("\t.b%sClrUsed = %i\r\n", szV, pbmih->biClrUsed) ;
    printf("\t.b%sClrImportant = %i\r\n\r\n", szV, 
                pbmih->biClrImportant) ;



    DWORD biClrUsed = 0;

    DWORD  iNumColors  =0;

    HPALETTE     hPalette = NULL;

    if (InfoHeadSize == sizeof (BITMAPINFOHEADER)){

        biClrUsed = pbmih->biClrUsed ;


        if(biClrUsed == 0){

            if(pbmih->biBitCount <16){

                iNumColors = 1<<pbmih->biBitCount ;
            }

        }else{

            iNumColors = biClrUsed ;
        }

        if(iNumColors >0){


             int          i ;
             LOGPALETTE * plp ;
             RGBQUAD    * prgb ;        
             plp = (LOGPALETTE *)malloc (sizeof (LOGPALETTE) * 
                                 (iNumColors - 1) * sizeof (PALETTEENTRY)) ;    


             plp->palVersion    = 0x0300 ;
             plp->palNumEntries = iNumColors ;

             for (i = 0 ; i < iNumColors ; i++)
             {
                  prgb = (RGBQUAD *) (((BYTE *) pbmih) + 
                                   pbmih->biSize)  + i;

                  plp->palPalEntry[i].peRed   = prgb->rgbRed ;
                  plp->palPalEntry[i].peGreen = prgb->rgbGreen ;
                  plp->palPalEntry[i].peBlue  = prgb->rgbBlue ;
                  plp->palPalEntry[i].peFlags = 0 ;
             }

             hPalette = CreatePalette (plp) ;
             free (plp) ;
        }




        if(hPalette){


               SelectPalette (hdcWindow, hPalette, FALSE) ;
               RealizePalette (hdcWindow) ;         
        }

             SetDIBitsToDevice (hdcWindow, 
                                  0,   
                                  0,   
                                  pbmih->biWidth, 
                                  pbmih->biHeight,
                                  0,                            
                                  0,                            
                                  0,                            
                                  pbmih->biHeight,  
                                  ((BYTE *)pbmih)+pbmih->biSize + sizeof (RGBQUAD)*iNumColors, 
                                  (BITMAPINFO *)pbmih, 
                                  DIB_RGB_COLORS) ;



    }else{


        printf("This BMP File  is not BITMAPINFOHEADER \r\n");
    }





}

在 OnInitDialog 中添加如下代码:

    AllocConsole(); 
    SetConsoleTitle(_T("debug console")); 
    freopen("CONOUT$","w",stdout); 

    printf("Hello\r\n");

有一个地方需要注意:

    HWND hWnd;
    HDC hdcWindow ;


    hWnd = AfxGetMainWnd()->m_hWnd;

    hdcWindow =::GetDC(hWnd);

GetDC 前面需要添加 ::符号

显示效果:
这里写图片描述

这里写图片描述

工程如下:
https://download.csdn.net/download/wowocpp/10512121

猜你喜欢

转载自blog.csdn.net/wowocpp/article/details/80875876