您的位置:首页 > 其它

图像拉伸,放大缩小算法函数

2008-12-30 13:15 471 查看
平滑放大缩小拉伸图像,本函数同时具有很高的效率。
其中BITMAP24结构和BITMAP 结构类似,在这里你可以假设两者相同。
pMapX,pMapY用于建立积卷映射表,同时将浮点运算转换成浮点运算。
void ImageStretch(BITMAP24 & dest,const BITMAP24 & src)
{
    ASSERT(dest.bmWidth>0 && dest.bmHeight>0);
    ASSERT(src.bmWidth>0 && src.bmHeight>0);

    double fZoomX = (double)dest.bmWidth/(double)src.bmWidth;
    double fZoomY = (double)dest.bmHeight/(double)src.bmHeight;

    LONG        i;
    POINTMAP *  pMapX;
    POINTMAP *  pMapY;
    double      fMin,fMax;

    pMapX = CImageDataMgr::instance().AllocXPointMap(dest.bmWidth);
    pMapY = CImageDataMgr::instance().AllocYPointMap(dest.bmHeight);

    // 初始化pMapX
    if (fZoomX<1.0f)
    {
        for (i=0;i<dest.bmWidth;i++)
        {
            fMin = i/fZoomX;
            fMax = (i+1)/fZoomX;

            pMapX[i].ps  = (int)fMin;
            pMapX[i].pe  = (int)fMax;

            if (pMapX[i].ps>=src.bmWidth) pMapX[i].ps=src.bmWidth-1;
            if (pMapX[i].pe>=src.bmWidth) pMapX[i].pe=src.bmWidth-1;

            pMapX[i].ws = (int)((pMapX[i].ps+1.0f-fMin)*fZoomX*256);
            pMapX[i].we = (int)((fMax-pMapX[i].pe)*fZoomX*256);
            pMapX[i].wi = 256-pMapX[i].ws-pMapX[i].we;
        }
    } else if (fZoomX==1.0f)
    {
        for (i=0;i<dest.bmWidth;i++)
        {
            pMapX[i].ps = i;
            pMapX[i].pe = i;
            pMapX[i].ws = 256;
            pMapX[i].we = 0;
        }
    } else if (fZoomX>1.0f)
    {
        for (i=0;i<dest.bmWidth;i++)
        {
            fMin = i/fZoomX;
            pMapX[i].ps = (LONG)fMin;
            pMapX[i].pe = pMapX[i].ps+1;
            if (pMapX[i].ps>=src.bmWidth) pMapX[i].ps=src.bmWidth-1;
            if (pMapX[i].pe>=src.bmWidth) pMapX[i].pe=src.bmWidth-1;
            fMin -= pMapX[i].ps;
            pMapX[i].we = (LONG)(fMin * 256);
            pMapX[i].ws = 256 - pMapX[i].we;
        }
    }

    // 初始化pMapY
    if (fZoomY<1.0f)
    {
        for (i=0;i<dest.bmHeight;i++)
        {
            fMin = i/fZoomY;
            fMax = (i+1)/fZoomY;

            pMapY[i].ps  = (int)fMin;
            pMapY[i].pe  = (int)fMax;

            if (pMapY[i].ps>=src.bmHeight) pMapY[i].ps=src.bmHeight-1;
            if (pMapY[i].pe>=src.bmHeight) pMapY[i].pe=src.bmHeight-1;

            pMapY[i].ws = (int)((pMapY[i].ps+1.0f-fMin)*fZoomY*256);
            pMapY[i].we = (int)((fMax-pMapY[i].pe)*fZoomY*256);
            pMapY[i].wi = 256-pMapY[i].ws-pMapY[i].we;
        }
    } else if (fZoomY==1.0f)
    {
        for (i=0;i<dest.bmHeight;i++)
        {
            pMapY[i].ps = i;
            pMapY[i].pe = i;
            pMapY[i].ws = 256;
            pMapY[i].we = 0;
        }
    } else if (fZoomY>1.0f)
    {
        for (i=0;i<dest.bmHeight;i++)
        {
            fMin = i/fZoomY;
            pMapY[i].ps = (LONG)fMin;
            pMapY[i].pe = pMapY[i].ps+1;
            if (pMapY[i].ps>=src.bmWidth) pMapY[i].ps=src.bmWidth-1;
            if (pMapY[i].pe>=src.bmWidth) pMapY[i].pe=src.bmWidth-1;
            fMin -= pMapY[i].ps;
            pMapY[i].we = (LONG)(fMin * 256);
            pMapY[i].ws = 256 - pMapY[i].we;
        }
    }

    LONG xd,yd;
    LONG ld,pd;
    LONG ls, ps,pe,pi;

    LONG psY,peY,psX,peX;
    LONG wsY,weY,wiY;
    LONG wsX,weX,wiX;

    LONG rvs, gvs, bvs;
    LONG rve, gve, bve;
    LONG rvi, gvi, bvi;
    LONG rv,  gv,  bv;
    BYTE * bsDest = dest.bmBits;
    BYTE * bsSrc  = src.bmBits;

    LONG xi,yi;

    ld  = 0;

    for (yd=0;yd<dest.bmHeight;yd++)
    {
        psY = pMapY[yd].ps;
        peY = pMapY[yd].pe;

        wsY = pMapY[yd].ws;
        weY = pMapY[yd].we;
        wiY = pMapY[yd].wi;

        pd  = ld;

        for (xd=0;xd<dest.bmWidth;xd++)
        {
            psX     = pMapX[xd].ps;
            peX     = pMapX[xd].pe;
            
            wsX     = pMapX[xd].ws;
            weX     = pMapX[xd].we;
            wiX     = pMapX[xd].wi;

            if (psY==peY)
            {
                ls = src.bmWidthBytes * psY;
                ps = ls + psX * 3;
                if (psX==peX)
                {
                    bsDest[pd] = bsSrc[ps];
                    bsDest[pd+1] = bsSrc[ps+1];
                    bsDest[pd+2] = bsSrc[ps+2];
                } else if (peX-1==psX)
                {
                    pe = ps + 3;
                    bsDest[pd] = (BYTE)((bsSrc[ps] * wsX 
                                        + bsSrc[pe] * weX)>>8);
                    bsDest[pd+1] = (BYTE)((bsSrc[ps+1] * wsX 
                                        + bsSrc[pe+1] * weX)>>8);
                    bsDest[pd+2] = (BYTE)((bsSrc[ps+2] * wsX 
                                        + bsSrc[pe+2] * weX)>>8);
                } else {
                    bv = 0, gv = 0, rv = 0;

                    pi = ps +3;
                    for (xi = psX+1;xi<peX;xi++)
                    {
                        bv += bsSrc[pi];
                        gv += bsSrc[pi+1];
                        rv += bsSrc[pi+2];
                        pi +=3;
                    }

                    bv = bv*wiX/(peX-psX-1);
                    gv = gv*wiX/(peX-psX-1);
                    rv = rv*wiX/(peX-psX-1);

                    bv += bsSrc[ps] * wsX;
                    gv += bsSrc[ps+1] * wsX;
                    rv += bsSrc[ps+2] * wsX;

                    pe = ls + peX * 3;

                    bv += bsSrc[pe] * weX;
                    gv += bsSrc[pe+1] * weX;
                    rv += bsSrc[pe+2] * weX;

                    bsDest[pd] =   (BYTE)(bv>>8);
                    bsDest[pd+1] = (BYTE)(gv>>8);
                    bsDest[pd+2] = (BYTE)(rv>>8);
                }
            } else if (peY-1==psY)
            {
                ls = src.bmWidthBytes * psY;
                ps = ls + psX * 3;

                if (psX==peX)
                {
                    bv = bsSrc[ps];
                    gv = bsSrc[ps+1];
                    rv = bsSrc[ps+2];
                } else if (peX-1==psX)
                {
                    pe = ps + 3;
                    bv = (BYTE)((bsSrc[ps] * wsX 
                                + bsSrc[pe] * weX)>>8);
                    gv = (BYTE)((bsSrc[ps+1] * wsX 
                                + bsSrc[pe+1] * weX)>>8);
                    rv = (BYTE)((bsSrc[ps+2] * wsX 
                                + bsSrc[pe+2] * weX)>>8);
                } else {
                    bv = 0, gv = 0, rv = 0;

                    pi = ps +3;
                    for (xi = psX+1;xi<peX;xi++)
                    {
                        bv += bsSrc[pi];
                        gv += bsSrc[pi+1];
                        rv += bsSrc[pi+2];
                        pi +=3;
                    }

                    bv = bv*wiX/(peX-psX-1);
                    gv = gv*wiX/(peX-psX-1);
                    rv = rv*wiX/(peX-psX-1);

                    bv += bsSrc[ps] * wsX;
                    gv += bsSrc[ps+1] * wsX;
                    rv += bsSrc[ps+2] * wsX;

                    pe = ls + peX * 3;

                    bv += bsSrc[pe] * weX;
                    gv += bsSrc[pe+1] * weX;
                    rv += bsSrc[pe+2] * weX;

                    bv = bv>>8;
                    gv = gv>>8;
                    rv = rv>>8;
                }

                bvs = bv;
                gvs = gv;
                rvs = rv;

                ls = peY * src.bmWidthBytes;
                ps = ls + psX * 3;

                if (psX==peX)
                {
                    bv = bsSrc[ps];
                    gv = bsSrc[ps+1];
                    rv = bsSrc[ps+2];
                } else if (peX-1==psX)
                {
                    pe = ps + 3;
                    bv = (BYTE)((bsSrc[ps] * wsX 
                                + bsSrc[pe] * weX)>>8);
                    gv = (BYTE)((bsSrc[ps+1] * wsX 
                                + bsSrc[pe+1] * weX)>>8);
                    rv = (BYTE)((bsSrc[ps+2] * wsX 
                                + bsSrc[pe+2] * weX)>>8);
                } else {
                    bv = 0, gv = 0, rv = 0;

                    pi = ps +3;
                    for (xi = psX+1;xi<peX;xi++)
                    {
                        bv += bsSrc[pi];
                        gv += bsSrc[pi+1];
                        rv += bsSrc[pi+2];
                        pi +=3;
                    }

                    bv = bv*wiX/(peX-psX-1);
                    gv = gv*wiX/(peX-psX-1);
                    rv = rv*wiX/(peX-psX-1);

                    bv += bsSrc[ps] * wsX;
                    gv += bsSrc[ps+1] * wsX;
                    rv += bsSrc[ps+2] * wsX;

       
e023
             pe = ls + peX * 3;

                    bv += bsSrc[pe] * weX;
                    gv += bsSrc[pe+1] * weX;
                    rv += bsSrc[pe+2] * weX;

                    bv = bv>>8;
                    gv = gv>>8;
                    rv = rv>>8;
                }

                bve = bv;
                gve = gv;
                rve = rv;

                bsDest[pd]   = (BYTE)((bvs * wsY + bve * weY)>>8);
                bsDest[pd+1] = (BYTE)((gvs * wsY + gve * weY)>>8);
                bsDest[pd+2] = (BYTE)((rvs * wsY + rve * weY)>>8);
            } else {
                // 计算中间部分 bvi;
                bvi = 0, gvi = 0, rvi = 0;

                for (yi = psY+1; yi<peY;yi++)
                {
                    ls = src.bmWidthBytes * yi;
                    ps = ls + psX * 3;

                    if (psX==peX)
                    {
                        bv = bsSrc[ps];
                        gv = bsSrc[ps+1];
                        rv = bsSrc[ps+2];
                    } else if (peX-1==psX)
                    {
                        pe = ps + 3;
                        bv = (BYTE)((bsSrc[ps] * wsX 
                                    + bsSrc[pe] * weX)>>8);
                        gv = (BYTE)((bsSrc[ps+1] * wsX 
                                    + bsSrc[pe+1] * weX)>>8);
                        rv = (BYTE)((bsSrc[ps+2] * wsX 
                                    + bsSrc[pe+2] * weX)>>8);
                    } else {
                        bv = 0, gv = 0, rv = 0;

                        pi = ps +3;
                        for (xi = psX+1;xi<peX;xi++)
                        {
                            bv += bsSrc[pi];
                            gv += bsSrc[pi+1];
                            rv += bsSrc[pi+2];
                            pi +=3;
                        }

                        bv = bv*wiX/(peX-psX-1);
                        gv = gv*wiX/(peX-psX-1);
                        rv = rv*wiX/(peX-psX-1);

                        bv += bsSrc[ps] * wsX;
                        gv += bsSrc[ps+1] * wsX;
                        rv += bsSrc[ps+2] * wsX;

                        pe = ls + peX * 3;

                        bv += bsSrc[pe] * weX;
                        gv += bsSrc[pe+1] * weX;
                        rv += bsSrc[pe+2] * weX;

                        bv = bv>>8;
                        gv = gv>>8;
                        rv = rv>>8;
                    }

                    bvi += bv;
                    gvi += gv;
                    rvi += rv;
                }

                // 计算vs
                ls = src.bmWidthBytes * psY;
                ps = ls + psX * 3;

                if (psX==peX)
                {
                    bv = bsSrc[ps];
                    gv = bsSrc[ps+1];
                    rv = bsSrc[ps+2];
                } else if (peX-1==psX)
                {
                    pe = ps + 3;
                    bv = (BYTE)((bsSrc[ps] * wsX 
                                + bsSrc[pe] * weX)>>8);
                    gv = (BYTE)((bsSrc[ps+1] * wsX 
                                + bsSrc[pe+1] * weX)>>8);
                    rv = (BYTE)((bsSrc[ps+2] * wsX 
                                + bsSrc[pe+2] * weX)>>8);
                } else {
                    bv = 0, gv = 0, rv = 0;

                    pi = ps +3;
                    for (xi = psX+1;xi<peX;xi++)
                    {
                        bv += bsSrc[pi];
                        gv += bsSrc[pi+1];
                        rv += bsSrc[pi+2];
                        pi +=3;
                    }

                    bv = bv*wiX/(peX-psX-1);
                    gv = gv*wiX/(peX-psX-1);
                    rv = rv*wiX/(peX-psX-1);

                    bv += bsSrc[ps] * wsX;
                    gv += bsSrc[ps+1] * wsX;
                    rv += bsSrc[ps+2] * wsX;

                    pe = ls + peX * 3;

                    bv += bsSrc[pe] * weX;
                    gv += bsSrc[pe+1] * weX;
                    rv += bsSrc[pe+2] * weX;

                    bv = bv>>8;
                    gv = gv>>8;
                    rv = rv>>8;
                }

                bvs = bv;
                gvs = gv;
                rvs = rv;

                ls = src.bmWidthBytes * peY;
                ps = ls + psX * 3;

                if (psX==peX)
                {
                    bv = bsSrc[ps];
                    gv = bsSrc[ps+1];
                    rv = bsSrc[ps+2];
                } else if (peX-1==psX)
                {
                    pe = ps + 3;
                    bv = (BYTE)((bsSrc[ps] * wsX 
                                + bsSrc[pe] * weX)>>8);
                    gv = (BYTE)((bsSrc[ps+1] * wsX 
                                + bsSrc[pe+1] * weX)>>8);
                    rv = (BYTE)((bsSrc[ps+2] * wsX 
                                + bsSrc[pe+2] * weX)>>8);
                } else {
                    bv = 0, gv = 0, rv = 0;

                    pi = ps +3;
                    for (xi = psX+1;xi<peX;xi++)
                    {
                        bv += bsSrc[pi];
                        gv += bsSrc[pi+1];
                        rv += bsSrc[pi+2];
                        pi +=3;
                    }

                    bv = bv*wiX/(peX-psX-1);
                    gv = gv*wiX/(peX-psX-1);
                    rv = rv*wiX/(peX-psX-1);

                    bv += bsSrc[ps] * wsX;
                    gv += bsSrc[ps+1] * wsX;
                    rv += bsSrc[ps+2] * wsX;

                    pe = ls + peX * 3;

                    bv += bsSrc[pe] * weX;
                    gv += bsSrc[pe+1] * weX;
                    rv += bsSrc[pe+2] * weX;

                    bv = bv>>8;
                    gv = gv>>8;
                    rv = rv>>8;
                }

                bve = bv;
                gve = gv;
                rve = rv;

                bv = bvs * wsY + bvi * wiY / (peY - psY -1) + bve * weY;
                gv = gvs * wsY + gvi * wiY / (peY - psY -1) + gve * weY;
                rv = rvs * wsY + rvi * wiY / (peY - psY -1) + rve * weY;

                bsDest[pd] = (BYTE)(bv>>8);
                bsDest[pd+1] = (BYTE)(gv>>8);
                bsDest[pd+2] = (BYTE)(rv>>8);
            }

            pd += 3;
        }
        ld += dest.bmWidthBytes;
    }
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  算法 byte