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

平滑放大缩小拉伸图像,本函数同时具有很高的效率。
其中BITMAP24结构和BITMAP 结构类似,在这里你可以假设两者相同。
pMapX,pMapY用于建立积卷映射表,同时将浮点运算转换成浮点运算。
  1. void ImageStretch(BITMAP24 & dest,const BITMAP24 & src)
  2. {
  3.     ASSERT(dest.bmWidth>0 && dest.bmHeight>0);
  4.     ASSERT(src.bmWidth>0 && src.bmHeight>0);
  5.     double fZoomX = (double)dest.bmWidth/(double)src.bmWidth;
  6.     double fZoomY = (double)dest.bmHeight/(double)src.bmHeight;
  7.     LONG        i;
  8.     POINTMAP *  pMapX;
  9.     POINTMAP *  pMapY;
  10.     double      fMin,fMax;
  11.     pMapX = CImageDataMgr::instance().AllocXPointMap(dest.bmWidth);
  12.     pMapY = CImageDataMgr::instance().AllocYPointMap(dest.bmHeight);
  13.     // 初始化pMapX
  14.     if (fZoomX<1.0f)
  15.     {
  16.         for (i=0;i
  17.         {
  18.             fMin = i/fZoomX;
  19.             fMax = (i+1)/fZoomX;
  20.             pMapX[i].ps  = (int)fMin;
  21.             pMapX[i].pe  = (int)fMax;
  22.             if (pMapX[i].ps>=src.bmWidth) pMapX[i].ps=src.bmWidth-1;
  23.             if (pMapX[i].pe>=src.bmWidth) pMapX[i].pe=src.bmWidth-1;
  24.             pMapX[i].ws = (int)((pMapX[i].ps+1.0f-fMin)*fZoomX*256);
  25.             pMapX[i].we = (int)((fMax-pMapX[i].pe)*fZoomX*256);
  26.             pMapX[i].wi = 256-pMapX[i].ws-pMapX[i].we;
  27.         }
  28.     } else if (fZoomX==1.0f)
  29.     {
  30.         for (i=0;i
  31.         {
  32.             pMapX[i].ps = i;
  33.             pMapX[i].pe = i;
  34.             pMapX[i].ws = 256;
  35.             pMapX[i].we = 0;
  36.         }
  37.     } else if (fZoomX>1.0f)
  38.     {
  39.         for (i=0;i
  40.         {
  41.             fMin = i/fZoomX;
  42.             pMapX[i].ps = (LONG)fMin;
  43.             pMapX[i].pe = pMapX[i].ps+1;
  44.             if (pMapX[i].ps>=src.bmWidth) pMapX[i].ps=src.bmWidth-1;
  45.             if (pMapX[i].pe>=src.bmWidth) pMapX[i].pe=src.bmWidth-1;
  46.             fMin -= pMapX[i].ps;
  47.             pMapX[i].we = (LONG)(fMin * 256);
  48.             pMapX[i].ws = 256 - pMapX[i].we;
  49.         }
  50.     }
  51.     // 初始化pMapY
  52.     if (fZoomY<1.0f)
  53.     {
  54.         for (i=0;i
  55.         {
  56.             fMin = i/fZoomY;
  57.             fMax = (i+1)/fZoomY;
  58.             pMapY[i].ps  = (int)fMin;
  59.             pMapY[i].pe  = (int)fMax;
  60.             if (pMapY[i].ps>=src.bmHeight) pMapY[i].ps=src.bmHeight-1;
  61.             if (pMapY[i].pe>=src.bmHeight) pMapY[i].pe=src.bmHeight-1;
  62.             pMapY[i].ws = (int)((pMapY[i].ps+1.0f-fMin)*fZoomY*256);
  63.             pMapY[i].we = (int)((fMax-pMapY[i].pe)*fZoomY*256);
  64.             pMapY[i].wi = 256-pMapY[i].ws-pMapY[i].we;
  65.         }
  66.     } else if (fZoomY==1.0f)
  67.     {
  68.         for (i=0;i
  69.         {
  70.             pMapY[i].ps = i;
  71.             pMapY[i].pe = i;
  72.             pMapY[i].ws = 256;
  73.             pMapY[i].we = 0;
  74.         }
  75.     } else if (fZoomY>1.0f)
  76.     {
  77.         for (i=0;i
  78.         {
  79.             fMin = i/fZoomY;
  80.             pMapY[i].ps = (LONG)fMin;
  81.             pMapY[i].pe = pMapY[i].ps+1;
  82.             if (pMapY[i].ps>=src.bmWidth) pMapY[i].ps=src.bmWidth-1;
  83.             if (pMapY[i].pe>=src.bmWidth) pMapY[i].pe=src.bmWidth-1;
  84.             fMin -= pMapY[i].ps;
  85.             pMapY[i].we = (LONG)(fMin * 256);
  86.             pMapY[i].ws = 256 - pMapY[i].we;
  87.         }
  88.     }
  89.     LONG xd,yd;
  90.     LONG ld,pd;
  91.     LONG ls, ps,pe,pi;
  92.     LONG psY,peY,psX,peX;
  93.     LONG wsY,weY,wiY;
  94.     LONG wsX,weX,wiX;
  95.     LONG rvs, gvs, bvs;
  96.     LONG rve, gve, bve;
  97.     LONG rvi, gvi, bvi;
  98.     LONG rv,  gv,  bv;
  99.     BYTE * bsDest = dest.bmBits;
  100.     BYTE * bsSrc  = src.bmBits;
  101.     LONG xi,yi;
  102.     ld  = 0;
  103.     for (yd=0;yd
  104.     {
  105.         psY = pMapY[yd].ps;
  106.         peY = pMapY[yd].pe;
  107.         wsY = pMapY[yd].ws;
  108.         weY = pMapY[yd].we;
  109.         wiY = pMapY[yd].wi;
  110.         pd  = ld;
  111.         for (xd=0;xd
  112.         {
  113.             psX     = pMapX[xd].ps;
  114.             peX     = pMapX[xd].pe;
  115.             
  116.             wsX     = pMapX[xd].ws;
  117.             weX     = pMapX[xd].we;
  118.             wiX     = pMapX[xd].wi;
  119.             if (psY==peY)
  120.             {
  121.                 ls = src.bmWidthBytes * psY;
  122.                 ps = ls + psX * 3;
  123.                 if (psX==peX)
  124.                 {
  125.                     bsDest[pd] = bsSrc[ps];
  126.                     bsDest[pd+1] = bsSrc[ps+1];
  127.                     bsDest[pd+2] = bsSrc[ps+2];
  128.                 } else if (peX-1==psX)
  129.                 {
  130.                     pe = ps + 3;
  131.                     bsDest[pd] = (BYTE)((bsSrc[ps] * wsX 
  132.                                         + bsSrc[pe] * weX)>>8);
  133.                     bsDest[pd+1] = (BYTE)((bsSrc[ps+1] * wsX 
  134.                                         + bsSrc[pe+1] * weX)>>8);
  135.                     bsDest[pd+2] = (BYTE)((bsSrc[ps+2] * wsX 
  136.                                         + bsSrc[pe+2] * weX)>>8);
  137.                 } else {
  138.                     bv = 0, gv = 0, rv = 0;
  139.                     pi = ps +3;
  140.                     for (xi = psX+1;xi
  141.                     {
  142.                         bv += bsSrc[pi];
  143.                         gv += bsSrc[pi+1];
  144.                         rv += bsSrc[pi+2];
  145.                         pi +=3;
  146.                     }
  147.                     bv = bv*wiX/(peX-psX-1);
  148.                     gv = gv*wiX/(peX-psX-1);
  149.                     rv = rv*wiX/(peX-psX-1);
  150.                     bv += bsSrc[ps] * wsX;
  151.                     gv += bsSrc[ps+1] * wsX;
  152.                     rv += bsSrc[ps+2] * wsX;
  153.                     pe = ls + peX * 3;
  154.                     bv += bsSrc[pe] * weX;
  155.                     gv += bsSrc[pe+1] * weX;
  156.                     rv += bsSrc[pe+2] * weX;
  157.                     bsDest[pd] =   (BYTE)(bv>>8);
  158.                     bsDest[pd+1] = (BYTE)(gv>>8);
  159.                     bsDest[pd+2] = (BYTE)(rv>>8);
  160.                 }
  161.             } else if (peY-1==psY)
  162.             {
  163.                 ls = src.bmWidthBytes * psY;
  164.                 ps = ls + psX * 3;
  165.                 if (psX==peX)
  166.                 {
  167.                     bv = bsSrc[ps];
  168.                     gv = bsSrc[ps+1];
  169.                     rv = bsSrc[ps+2];
  170.                 } else if (peX-1==psX)
  171.                 {
  172.                     pe = ps + 3;
  173.                     bv = (BYTE)((bsSrc[ps] * wsX 
  174.                                 + bsSrc[pe] * weX)>>8);
  175.                     gv = (BYTE)((bsSrc[ps+1] * wsX 
  176.                                 + bsSrc[pe+1] * weX)>>8);
  177.                     rv = (BYTE)((bsSrc[ps+2] * wsX 
  178.                                 + bsSrc[pe+2] * weX)>>8);
  179.                 } else {
  180.                     bv = 0, gv = 0, rv = 0;
  181.                     pi = ps +3;
  182.                     for (xi = psX+1;xi
  183.                     {
  184.                         bv += bsSrc[pi];
  185.                         gv += bsSrc[pi+1];
  186.                         rv += bsSrc[pi+2];
  187.                         pi +=3;
  188.                     }
  189.                     bv = bv*wiX/(peX-psX-1);
  190.                     gv = gv*wiX/(peX-psX-1);
  191.                     rv = rv*wiX/(peX-psX-1);
  192.                     bv += bsSrc[ps] * wsX;
  193.                     gv += bsSrc[ps+1] * wsX;
  194.                     rv += bsSrc[ps+2] * wsX;
  195.                     pe = ls + peX * 3;
  196.                     bv += bsSrc[pe] * weX;
  197.                     gv += bsSrc[pe+1] * weX;
  198.                     rv += bsSrc[pe+2] * weX;
  199.                     bv = bv>>8;
  200.                     gv = gv>>8;
  201.                     rv = rv>>8;
  202.                 }
  203.                 bvs = bv;
  204.                 gvs = gv;
  205.                 rvs = rv;
  206.                 ls = peY * src.bmWidthBytes;
  207.                 ps = ls + psX * 3;
  208.                 if (psX==peX)
  209.                 {
  210.                     bv = bsSrc[ps];
  211.                     gv = bsSrc[ps+1];
  212.                     rv = bsSrc[ps+2];
  213.                 } else if (peX-1==psX)
  214.                 {
  215.                     pe = ps + 3;
  216.                     bv = (BYTE)((bsSrc[ps] * wsX 
  217.                                 + bsSrc[pe] * weX)>>8);
  218.                     gv = (BYTE)((bsSrc[ps+1] * wsX 
  219.                                 + bsSrc[pe+1] * weX)>>8);
  220.                     rv = (BYTE)((bsSrc[ps+2] * wsX 
  221.                                 + bsSrc[pe+2] * weX)>>8);
  222.                 } else {
  223.                     bv = 0, gv = 0, rv = 0;
  224.                     pi = ps +3;
  225.                     for (xi = psX+1;xi
  226.                     {
  227.                         bv += bsSrc[pi];
  228.                         gv += bsSrc[pi+1];
  229.                         rv += bsSrc[pi+2];
  230.                         pi +=3;
  231.                     }
  232.                     bv = bv*wiX/(peX-psX-1);
  233.                     gv = gv*wiX/(peX-psX-1);
  234.                     rv = rv*wiX/(peX-psX-1);
  235.                     bv += bsSrc[ps] * wsX;
  236.                     gv += bsSrc[ps+1] * wsX;
  237.                     rv += bsSrc[ps+2] * wsX;
  238.                     pe = ls + peX * 3;
  239.                     bv += bsSrc[pe] * weX;
  240.                     gv += bsSrc[pe+1] * weX;
  241.                     rv += bsSrc[pe+2] * weX;
  242.                     bv = bv>>8;
  243.                     gv = gv>>8;
  244.                     rv = rv>>8;
  245.                 }
  246.                 bve = bv;
  247.                 gve = gv;
  248.                 rve = rv;
  249.                 bsDest[pd]   = (BYTE)((bvs * wsY + bve * weY)>>8);
  250.                 bsDest[pd+1] = (BYTE)((gvs * wsY + gve * weY)>>8);
  251.                 bsDest[pd+2] = (BYTE)((rvs * wsY + rve * weY)>>8);
  252.             } else {
  253.                 // 计算中间部分 bvi;
  254.                 bvi = 0, gvi = 0, rvi = 0;
  255.                 for (yi = psY+1; yi
  256.                 {
  257.                     ls = src.bmWidthBytes * yi;
  258.                     ps = ls + psX * 3;
  259.                     if (psX==peX)
  260.                     {
  261.                         bv = bsSrc[ps];
  262.                         gv = bsSrc[ps+1];
  263.                         rv = bsSrc[ps+2];
  264.                     } else if (peX-1==psX)
  265.                     {
  266.                         pe = ps + 3;
  267.                         bv = (BYTE)((bsSrc[ps] * wsX 
  268.                                     + bsSrc[pe] * weX)>>8);
  269.                         gv = (BYTE)((bsSrc[ps+1] * wsX 
  270.                                     + bsSrc[pe+1] * weX)>>8);
  271.                         rv = (BYTE)((bsSrc[ps+2] * wsX 
  272.                                     + bsSrc[pe+2] * weX)>>8);
  273.                     } else {
  274.                         bv = 0, gv = 0, rv = 0;
  275.                         pi = ps +3;
  276.                         for (xi = psX+1;xi
  277.                         {
  278.                             bv += bsSrc[pi];
  279.                             gv += bsSrc[pi+1];
  280.                             rv += bsSrc[pi+2];
  281.                             pi +=3;
  282.                         }
  283.                         bv = bv*wiX/(peX-psX-1);
  284.                         gv = gv*wiX/(peX-psX-1);
  285.                         rv = rv*wiX/(peX-psX-1);
  286.                         bv += bsSrc[ps] * wsX;
  287.                         gv += bsSrc[ps+1] * wsX;
  288.                         rv += bsSrc[ps+2] * wsX;
  289.                         pe = ls + peX * 3;
  290.                         bv += bsSrc[pe] * weX;
  291.                         gv += bsSrc[pe+1] * weX;
  292.                         rv += bsSrc[pe+2] * weX;
  293.                         bv = bv>>8;
  294.                         gv = gv>>8;
  295.                         rv = rv>>8;
  296.                     }
  297.                     bvi += bv;
  298.                     gvi += gv;
  299.                     rvi += rv;
  300.                 }
  301.                 // 计算vs
  302.                 ls = src.bmWidthBytes * psY;
  303.                 ps = ls + psX * 3;
  304.                 if (psX==peX)
  305.                 {
  306.                     bv = bsSrc[ps];
  307.                     gv = bsSrc[ps+1];
  308.                     rv = bsSrc[ps+2];
  309.                 } else if (peX-1==psX)
  310.                 {
  311.                     pe = ps + 3;
  312.                     bv = (BYTE)((bsSrc[ps] * wsX 
  313.                                 + bsSrc[pe] * weX)>>8);
  314.                     gv = (BYTE)((bsSrc[ps+1] * wsX 
  315.                                 + bsSrc[pe+1] * weX)>>8);
  316.                     rv = (BYTE)((bsSrc[ps+2] * wsX 
  317.                                 + bsSrc[pe+2] * weX)>>8);
  318.                 } else {
  319.                     bv = 0, gv = 0, rv = 0;
  320.                     pi = ps +3;
  321.                     for (xi = psX+1;xi
  322.                     {
  323.                         bv += bsSrc[pi];
  324.                         gv += bsSrc[pi+1];
  325.                         rv += bsSrc[pi+2];
  326.                         pi +=3;
  327.                     }
  328.                     bv = bv*wiX/(peX-psX-1);
  329.                     gv = gv*wiX/(peX-psX-1);
  330.                     rv = rv*wiX/(peX-psX-1);
  331.                     bv += bsSrc[ps] * wsX;
  332.                     gv += bsSrc[ps+1] * wsX;
  333.                     rv += bsSrc[ps+2] * wsX;
  334.                     pe = ls + peX * 3;
  335.                     bv += bsSrc[pe] * weX;
  336.                     gv += bsSrc[pe+1] * weX;
  337.                     rv += bsSrc[pe+2] * weX;
  338.                     bv = bv>>8;
  339.                     gv = gv>>8;
  340.                     rv = rv>>8;
  341.                 }
  342.                 bvs = bv;
  343.                 gvs = gv;
  344.                 rvs = rv;
  345.                 ls = src.bmWidthBytes * peY;
  346.                 ps = ls + psX * 3;
  347.                 if (psX==peX)
  348.                 {
  349.                     bv = bsSrc[ps];
  350.                     gv = bsSrc[ps+1];
  351.                     rv = bsSrc[ps+2];
  352.                 } else if (peX-1==psX)
  353.                 {
  354.                     pe = ps + 3;
  355.                     bv = (BYTE)((bsSrc[ps] * wsX 
  356.                                 + bsSrc[pe] * weX)>>8);
  357.                     gv = (BYTE)((bsSrc[ps+1] * wsX 
  358.                                 + bsSrc[pe+1] * weX)>>8);
  359.                     rv = (BYTE)((bsSrc[ps+2] * wsX 
  360.                                 + bsSrc[pe+2] * weX)>>8);
  361.                 } else {
  362.                     bv = 0, gv = 0, rv = 0;
  363.                     pi = ps +3;
  364.                     for (xi = psX+1;xi
  365.                     {
  366.                         bv += bsSrc[pi];
  367.                         gv += bsSrc[pi+1];
  368.                         rv += bsSrc[pi+2];
  369.                         pi +=3;
  370.                     }
  371.                     bv = bv*wiX/(peX-psX-1);
  372.                     gv = gv*wiX/(peX-psX-1);
  373.                     rv = rv*wiX/(peX-psX-1);
  374.                     bv += bsSrc[ps] * wsX;
  375.                     gv += bsSrc[ps+1] * wsX;
  376.                     rv += bsSrc[ps+2] * wsX;
  377.                     pe = ls + peX * 3;
  378.                     bv += bsSrc[pe] * weX;
  379.                     gv += bsSrc[pe+1] * weX;
  380.                     rv += bsSrc[pe+2] * weX;
  381.                     bv = bv>>8;
  382.                     gv = gv>>8;
  383.                     rv = rv>>8;
  384.                 }
  385.                 bve = bv;
  386.                 gve = gv;
  387.                 rve = rv;
  388.                 bv = bvs * wsY + bvi * wiY / (peY - psY -1) + bve * weY;
  389.                 gv = gvs * wsY + gvi * wiY / (peY - psY -1) + gve * weY;
  390.                 rv = rvs * wsY + rvi * wiY / (peY - psY -1) + rve * weY;
  391.                 bsDest[pd] = (BYTE)(bv>>8);
  392.                 bsDest[pd+1] = (BYTE)(gv>>8);
  393.                 bsDest[pd+2] = (BYTE)(rv>>8);
  394.             }
  395.             pd += 3;
  396.         }
  397.         ld += dest.bmWidthBytes;
  398.     }
  399. }

你可能感兴趣的:(图像拉伸,放大缩小算法函数)