我说的位图缩放是指将一个位图文件first.bmp,按比例n缩放后存入第二个位图文件second.bmp,如n=0.5,second.bmp的大小是原来first.bmp的一半。不是使用StretchBlt实现缩放显示!
请高手指点!

解决方案 »

  1.   

    如果是要缩放算法的话,可以用图形的四点转正来做,然后再用双线性插值
    http://expert.csdn.net/Expert/topic/2077/2077097.xml?temp=.140423
    这里有讲。
      

  2.   

    这属于最基本的图像变换处理了,基本思路是遍历目标图的每一个像素点,根据比例因子去
    计算该点在源图是哪一点,将那一点的像素值存入目标图就行了。伪代码:
    缩放比率:n
    目标图:pDst,nDstW(=nSrcW*n),nDstH(=nSrcH*n)
    原图:pSrc,nSrcW,nSrcHfor(int j; j<nDstH; j++)
        for(int i; i<nDstW; i++)
            {
                 pDst = f(pSrc);
                 pDst++;
            }至于目标图到源图的对应关系f,我想你应该可以自己推出来了吧。
      

  3.   

    这里有一个处理图形的库啦,你可以研究一下,添加不超过十行代码,应该就能完成你的功能
    http://www.vchelp.net/vchelp/file2002_4/flib.asp?type_id=18&class_id=1&cata_id=12&article_id=907
      

  4.   

    CxImage
    www.codeproject.com--------------
              May you succeed!
                 -------------------
      

  5.   

    上面都是高手在论道,都是自己写的算法,小弟是个新人,也发表一下愚见。
    StretchBlt是可以实现缩放的,为什么不用它把一个BMP用StretchBlt到一个内存DC中呢,然后再DDBTODIB不就可以了。
    不过这个不是算法了,博大家一笑而已
      

  6.   

    如果你是想学习的话,就不应该嫌它难。况且我说过,这还只是图像处理的最基本简单的东西。
    就是这个简单的缩放变换,也还有可扩展的地方,比如你想得到更好的画质,要用到二次线性插
    值。得到非常完美的画质,要用到高阶插值。当然,如果你要只想简单的得到这样一个效果,用StretchBlt完全可以达到同样的目的。只不过
    你要StretchBlt到一个MemDC,然后Bitblt回源DC,这样就得到了新的被缩放过的位图。你保存
    的话,一定是新的位图。
      

  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);