我要对位图缩放,比如我有一个320X240的MFC的CBitmap,我象将其缩为160X120,怎么处理啊
或者是我有320X240的位图文件的头结构BITMAPINFOHEADER和数据部分缓冲,怎么变成
160X120的头和数据缓冲呢
最好有代码了,谢谢

解决方案 »

  1.   

    StretchBlt
    就可以实现对位图的缩放了!
    不过失真比较严重!
      

  2.   

    StretchBlt,是可以的,它会自己帮你删除一些行的,会失真
      

  3.   

    http://www.vctop.com/View.Asp?ID=391&CateID=1
      

  4.   

    StretchBlt简单好用。。只要缩放比例不太大看起来没多大的影响。。
      

  5.   

    如果只是单纯为了显示,就使用StretchBlt。
      

  6.   

    我自己处理了,StretchBlt是用户显示,
    应该对数据进行重新采样
      

  7.   

    CShowDibDoc*  pDoc = GetDocument();
    int    horizon; int    vertical; CScale      dlg;
        //读取放大或者缩小的比例
    if(dlg.DoModal()==IDOK)
    {
    horizon = dlg.m_horizon;//水平的比例
    vertical = dlg.m_vertical;//垂直的比例
    }
    else
    {
        return ;
    } LPBITMAPINFOHEADER    lpbmi; //BYTE*   lpDIBBits; lpbmi = (LPBITMAPINFOHEADER)GlobalLock((HGLOBAL)pDoc->m_Dib.m_hDIB); LPSTR   lpDIB; lpDIB = (LPSTR)GlobalLock((HGLOBAL) pDoc->m_Dib.m_hDIB); unsigned  char* lpDIBBits = (unsigned char *)::FindDIBBits(lpDIB); //lpDIBBits = (BYTE*)(lpbmi + sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD)*256); HANDLE  buffer; LPSTR   bufdata;
        //分配一块内存,用来存放信息头和调色板
    buffer = GlobalAlloc(GMEM_MOVEABLE|GMEM_ZEROINIT, sizeof(BITMAPINFO) + 256*sizeof(RGBQUAD));    bufdata = (LPSTR) GlobalLock((HGLOBAL) buffer);
        //将信息头和调色板暂时存放在刚分配的内存中
    for(int k=0; k<sizeof(BITMAPINFO) + 256*sizeof(RGBQUAD); k++)
    {
    *(bufdata + k) = *(lpDIB + k);
    } HANDLE    datahandle; LPSTR     data; int    height = lpbmi->biHeight; int    width = lpbmi->biWidth; int   lWidthBytes = WIDTHBYTES(width*8);
        //取出图像中原来的数据
    datahandle = GlobalAlloc(GMEM_MOVEABLE|GMEM_ZEROINIT, height*lWidthBytes); data = (LPSTR) GlobalLock((HGLOBAL) datahandle); for(int i=0; i<height; i++)
    {
    for(int j=0; j<width; j++)
    {
    *(data + i*lWidthBytes + j) = *(lpDIBBits + i*lWidthBytes + j);
    }
    }
        int    Sheight = height*vertical/100;             //缩小后的图像

    int    Swidth = width*horizon/100;   

        int   lwidthbytes = WIDTHBYTES(Swidth*8);//缩小后的
    //释放掉原来的内存快,重新分配内存。
    GlobalUnlock((HGLOBAL) pDoc->m_Dib.m_hDIB); GlobalFree((HGLOBAL) pDoc->m_Dib.m_hDIB); pDoc->m_Dib.m_hDIB = (HDIB)GlobalAlloc(GMEM_MOVEABLE|GMEM_ZEROINIT, sizeof(BITMAPINFO) + 256*sizeof(RGBQUAD) + Sheight*lwidthbytes);

    lpDIB = (LPSTR)GlobalLock((HGLOBAL) pDoc->m_Dib.m_hDIB);
    //将暂存的信息头和调色板重新放到新的内存中。
    for(int l=0; l<sizeof(BITMAPINFO) + 256*sizeof(RGBQUAD); l++)
    {
    *(lpDIB + l) = *(bufdata + l);
    }
    //调整信息头
    lpbmi = (LPBITMAPINFOHEADER)GlobalLock((HGLOBAL)pDoc->m_Dib.m_hDIB); lpbmi->biSizeImage = (lpbmi->biSizeImage*vertical*horizon)/10000; //lpbmi->biSize = lpbmi->biSize - (3*height*width/4); lpbmi->biHeight = Sheight; lpbmi->biWidth = Swidth; lpDIBBits = (unsigned char*)::FindDIBBits(lpDIB);
        //调整图像, 进行缩放。
    for( int a=0; a<Sheight; a++)
    {
    for(int b=0; b<Swidth; b++)
    {
    *(lpDIBBits + a*lwidthbytes + b) = *(data + (int)(a*100/vertical)*lWidthBytes + (int)(b*100/horizon));
    }
    }
    pDoc->SetModifiedFlag(TRUE); GlobalUnlock((HGLOBAL) buffer); GlobalFree((HGLOBAL) buffer); GlobalUnlock((HGLOBAL) datahandle); GlobalFree((HGLOBAL) datahandle); GlobalUnlock((HGLOBAL) pDoc->m_Dib.m_hDIB);

    //OnDoRealize((WPARAM)m_hWnd,0); OnInitialUpdate(); pDoc->UpdateAllViews(NULL);