用VC平台读入BMP图像并保存的程序

解决方案 »

  1.   

    使用CImage类,它可以读取并保存很多种图像格式
      

  2.   


    BOOL CFSBitmap::LoadBmpFile(LPCTSTR strFileName)
    {
    Free();

    HFILE              hf;
        LPBITMAPINFOHEADER lpImgData;
        LOGPALETTE         *pPal;
        LPRGBQUAD          lpRGB;
        HPALETTE           hPrevPalette; 
        HDC                hDc;
    HLOCAL             hPal;
    DWORD         ImgSize;
    DWORD              i;

        if((hf=_lopen(strFileName, OF_READ)) == HFILE_ERROR){
            MessageBox("BMP File  not found!","Error Message",MB_OK|MB_ICONEXCLAMATION);
            return FALSE;
    }
    m_strFileName = strFileName;
    _lread(hf,(LPSTR)&bf,sizeof(BITMAPFILEHEADER)); 
    _lread(hf,(LPSTR)&bi,sizeof(BITMAPINFOHEADER));
    LineBytes=(DWORD)WIDTHBYTES(bi.biWidth*bi.biBitCount);
    ImgSize=(DWORD)LineBytes*bi.biHeight;
        if(bi.biClrUsed!=0)
    NumColors=(DWORD)bi.biClrUsed;
    else
            switch(bi.biBitCount){
            case 1:
    NumColors=2;
    break;
    case 4:
    NumColors=16;
    break;
    case 8:
    NumColors=256;
    break;
    case 24:
    NumColors=0;
    break;
    default:
    MessageBox("Invalid color numbers!","Error Message",MB_OK|MB_ICONEXCLAMATION);
    _lclose(hf);
    return FALSE; 
    }
    if(bf.bfOffBits!=(DWORD)(NumColors*sizeof(RGBQUAD)+sizeof(BITMAPFILEHEADER)
    +sizeof(BITMAPINFOHEADER)))
    {
    MessageBox("Invalid color numbers!","Error Message" ,MB_OK|
    MB_ICONEXCLAMATION);
    _lclose(hf);
    return FALSE; 
    }
    bf.bfSize=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+NumColors*sizeof(RGBQUAD)+ImgSize;
    if((hImgData=GlobalAlloc(GHND,(DWORD)(sizeof(BITMAPINFOHEADER)+
    NumColors*sizeof(RGBQUAD)+ImgSize)))==NULL)
    {
    MessageBox("Error alloc memory!","ErrorMessage",MB_OK|
    MB_ICONEXCLAMATION);
    _lclose(hf);
    return FALSE;
    }

    lpImgData=(LPBITMAPINFOHEADER)GlobalLock(hImgData); 
        _llseek(hf,sizeof(BITMAPFILEHEADER),SEEK_SET);
    _hread(hf,(char *)lpImgData,(long)sizeof(BITMAPINFOHEADER)
    +(long)NumColors*sizeof(RGBQUAD)+ImgSize);
    _lclose(hf);
        if(NumColors!=0)
    {                    
    hPal=LocalAlloc(LHND,sizeof(LOGPALETTE) + NumColors* sizeof(PALETTEENTRY));
    pPal =(LOGPALETTE *)LocalLock(hPal);
    pPal->palNumEntries =(WORD) NumColors;
    pPal->palVersion    = 0x300;
    lpRGB = (LPRGBQUAD)((LPSTR)lpImgData + (DWORD)sizeof(BITMAPINFOHEADER));
    for (i = 0; i < NumColors; i++) {
    pPal->palPalEntry[i].peRed=lpRGB->rgbRed;
    pPal->palPalEntry[i].peGreen=lpRGB->rgbGreen;
    pPal->palPalEntry[i].peBlue=lpRGB->rgbBlue;
    pPal->palPalEntry[i].peFlags=(BYTE)0;
    lpRGB++;
    }
    hPalette=CreatePalette(pPal);
    LocalUnlock(hPal);
    LocalFree(hPal);
    }
    hDc=GetDC()->m_hDC;
    if(hPalette){
            hPrevPalette=SelectPalette(hDc,hPalette,FALSE);
    RealizePalette(hDc);
    }
    hBitmap=CreateDIBitmap(hDc, (LPBITMAPINFOHEADER)lpImgData, (LONG)CBM_INIT,
    (LPSTR)lpImgData+sizeof(BITMAPINFOHEADER) +NumColors*sizeof(RGBQUAD),
    (LPBITMAPINFO)lpImgData, DIB_RGB_COLORS);
    if(hPalette && hPrevPalette){
    SelectPalette(hDc,hPrevPalette,FALSE);
    RealizePalette(hDc);
    }

    ::ReleaseDC(this->m_hWnd, hDc);
    GlobalUnlock(hImgData); CRect rect;
    GetWindowRect(&rect);
    GetParent()->ScreenToClient(rect);
    rect.right = rect.left + bi.biWidth;
    rect.bottom = rect.top + bi.biHeight;
    MoveWindow(&rect);
    Invalidate();

    return true;
    }void CFSBitmap::Free()
    {
    if(hBitmap!=NULL){     
    DeleteObject(hBitmap);
    hBitmap=NULL;
    }
    if(hPalette!=NULL){                     
    DeleteObject(hPalette);
    hPalette=NULL;
    }
    if(hImgData!=NULL){
    GlobalUnlock(hImgData);
    GlobalFree(hImgData);  
    hImgData=NULL;
    }
    }
      

  3.   

    CxImage 非常好用的类http://baike.baidu.com/view/2126624.htm
      

  4.   

    VS 下用自带的CImage类就很方便。