怎样取出gif的第一帧,并把第一帧保存为bmp格式,能提供源码或者下载源码的地方(源码能够正确的运行),我在vchelp找到一个源码,结果不能运行,有n多个错误,要么*.cpp不全,就是*.h找不到。好象他们都不愿意公开,故意搞了很多bug在里面,郁闷中啊!

解决方案 »

  1.   

    用IPicture 可以得到gif图片的第一帧 IStream *pStm;
    CFileStatus fstatus;
    CFile file;
    LONG cb;
    CString sFileName;
    sFileName = "e:\\flagani.gif"; if(file.Open(sFileName,CFile::modeRead)&&
    file.GetStatus(sFileName,fstatus)&&((cb =fstatus.m_size)!= -1))
    {
    HGLOBAL hGlobal = GlobalAlloc(GMEM_MOVEABLE,cb);
    LPVOID pvData = NULL;
    if (hGlobal != NULL)
    {
    if ((pvData = GlobalLock(hGlobal))!= NULL)
    {
    file.ReadHuge(pvData,cb);
    GlobalUnlock(hGlobal);
    CreateStreamOnHGlobal(hGlobal,TRUE,&pStm);
    }
    }
    }
    IPicture *pPic;
    if (SUCCEEDED(OleLoadPicture(pStm,fstatus.m_size,TRUE,IID_IPicture,(LPVOID *)&pPic)))
    {
    OLE_XSIZE_HIMETRIC hmWidth,hmHeight;
    pPic->get_Width(&hmWidth);
    pPic->get_Height(&hmHeight); CDC *pDC = GetDC();
    CSize sz(hmWidth,hmHeight);
    if (pDC==NULL) 
    {
    CWindowDC dc(NULL);
    dc.HIMETRICtoDP(&sz); // convert to pixels

    else
    {
    pDC->HIMETRICtoDP(&sz);
    }
    CDC memDC;
    memDC.CreateCompatibleDC(pDC);
    CBitmap bmp;
    bmp.CreateCompatibleBitmap(pDC,sz.cx,sz.cy);
    memDC.SelectObject(bmp);
    memDC.FillRect(CRect(0,0,sz.cx,sz.cy),&CBrush(RGB(255,255,255)));//填充背景色 if(FAILED(pPic->Render(memDC.m_hDC,0,0,sz.cx,sz.cy,
    0, hmHeight, hmWidth, -hmHeight,NULL)))
    {
    AfxMessageBox("渲染图像失败!");
    return;
    }
    // pDC->BitBlt(0,0,sz.cx,sz.cy,&memDC,0,0,SRCCOPY);
    ReleaseDC(pDC);
    pPic->Release();
    pStm->Release(); SaveHBITMAPToBMP24((HBITMAP)bmp,"e:\\tt.bmp");//保存bmp
    }
    else
    {
    AfxMessageBox("从流中装载图像失败!");
    }
    //保存bmp文件
    BOOL SaveHBITMAPToBMP24(HBITMAP hBitmap,const char *pFileName)
    {
    if (hBitmap == NULL)
    return FALSE;
    //验证pFileName
    if (pFileName == NULL)
    return FALSE; //创建DIB
    BITMAP bm;
    if (::GetObject(hBitmap,sizeof(BITMAP),&bm) <= 0)
    return FALSE;
    long nBmpWidth = bm.bmWidth;
    long nBmpHeight = bm.bmHeight;
    long nBmpWidthBytes = (nBmpWidth*3+3)/4*4;
    long nImageSize24 = nBmpWidthBytes*nBmpHeight;
    BYTE *pSrc = (BYTE *)::GlobalAlloc(GPTR,nImageSize24);//source dib
    if (pSrc == NULL)
    return FALSE;
    /////////////////////////////////////////////
    BITMAPINFOHEADER bifh;
    bifh.biSize=sizeof(BITMAPINFOHEADER);
    bifh.biWidth=nBmpWidth;
    bifh.biHeight=nBmpHeight;
    bifh.biPlanes=1;
    bifh.biBitCount=24;//24 bit
    bifh.biCompression=0;
    bifh.biSizeImage=nImageSize24;
    bifh.biXPelsPerMeter=0;
    bifh.biYPelsPerMeter=0;
    bifh.biClrUsed=0;
    bifh.biClrImportant=0;
    HDC hDC = ::GetDC(NULL);
    long nRet;
    nRet = ::GetDIBits(hDC,hBitmap,0,nBmpHeight,pSrc,(BITMAPINFO*)&bifh,DIB_RGB_COLORS);
    if (nRet != nBmpHeight)
    {
    DeleteDC(hDC);
    GlobalFree(pSrc);
    return FALSE;
    }
    ::ReleaseDC(NULL,hDC);
    //////////////////////////////////////////
    BITMAPFILEHEADER bfh;
    bfh.bfReserved1=bfh.bfReserved2=0;
    bfh.bfType=((WORD)('M'<< 8)|'B');
    bfh.bfSize=54+nImageSize24;
    bfh.bfOffBits=54;
    FILE *stream;
    if( (stream = fopen( pFileName, "w" )) != NULL )
    {
    fwrite(&bfh,1,sizeof(BITMAPFILEHEADER),stream);
    fwrite(&bifh,1,sizeof(BITMAPINFOHEADER),stream);
    fwrite(pSrc,1,nImageSize24,stream);
    fclose( stream );
    }
    else
    return FALSE;
    GlobalFree(pSrc);
    return TRUE;
    }
      

  2.   

    用IPicture不错的,配合使用IStream
      

  3.   

    呵呵,自己分析一下gif的结构就ok了。
    源码一大堆呢~~~~~