resize.cpp
上传用户:yatsl7111
上传日期:2007-01-08
资源大小:1433k
文件大小:8k
源码类别:

图形图象

开发平台:

Visual C++

  1. /********************************************************************
  2. resize.cpp - ISee图像浏览器—图像处理模块图像重定义尺寸处理实现代码文件
  3.     版权所有(C) VCHelp-coPathway-ISee workgroup 2000 all member's
  4.     这一程序是自由软件,你可以遵照自由软件基金会出版的GNU 通用许可证
  5. 条款来修改和重新发布这一程序。或者用许可证的第二版,或者(根据你
  6. 的选择)用任何更新的版本。
  7.     发布这一程序的目的是希望它有用,但没有任何担保。甚至没有适合特定
  8. 目地的隐含的担保。更详细的情况请参阅GNU通用许可证。
  9.     你应该已经和程序一起收到一份GNU通用许可证(GPL)的副本。如果还没有,
  10. 写信给:
  11.     The Free Software Foundation, Inc.,  675  Mass Ave,  Cambridge,
  12.     MA02139,  USA
  13. 如果你在使用本软件时有什么问题或建议,用以下地址可以与我们取得联
  14. 系:
  15. http://isee.126.com
  16. http://www.vchelp.net
  17. 或:
  18. iseesoft@china.com
  19. 作者:临风
  20.    e-mail:ringphone@sina.com
  21.    功能实现:重定义图像尺寸
  22. 文件版本:
  23. Build 00617
  24. Date  2000-6-17
  25. ********************************************************************/
  26. #include "p_win.h"
  27. #include "..publicgol_proc.h"
  28. #include "filter.h"
  29. #include "resize.h"
  30. //重定义尺寸
  31. int Output_Resize(int width,int height,LPBYTE lpDestData)
  32. {
  33. LPBYTE lpData=(LPBYTE)lpProcInfo->_psbdata,lpBak,lpBako;
  34.    LPBYTE lpdData=lpDestData;
  35.    if(lpDestData==NULL )
  36.     return PROCERR_FALSE;
  37.    int skip = lpProcInfo->sImageInfo.bitperpix/8;
  38.    float x=(float)lpProcInfo->sImageInfo.width/(float)width;
  39.    float y=(float)lpProcInfo->sImageInfo.height/(float)height;
  40. float x_cnt,y_cnt=0.00;
  41.    lpBak=lpBako=lpData;
  42.    for(int j=0;j<height;j++)
  43.    {
  44. x_cnt=0.00;
  45.       for(int i=0;i<width;i++)
  46.       {
  47.          for(int k=0;k<skip;k++)
  48.          {
  49.             *lpdData=*lpData;
  50.             lpdData++;
  51.             lpData++;
  52.          }
  53.          x_cnt+=x;
  54.          lpData=lpBak+skip*(int)x_cnt;
  55.       }
  56. y_cnt+=y;
  57.       lpBak=lpBako+lpProcInfo->sImageInfo.width*skip*(int)y_cnt;
  58. lpData=lpBak;
  59.    }
  60.    return TRUE;
  61. }
  62. int Resize(int w,int h,int rs_flag,int rs_pos,COLORREF rs_bgcolor)
  63. {
  64.    // Add by YZ 2000-9-22. 因为图像处理模块始终工作于32位模式,所以直接乘4
  65. lpProcInfo->_pdbdata = (unsigned char*)New(w*h*4);
  66. //lpProcInfo->_pdbdata = (unsigned char*)New(w*h*(lpProcInfo->sImageInfo.bitperpix/8));
  67.    if(lpProcInfo->_pdbdata==NULL)
  68.    {
  69.     lpProcInfo->result=PR_MEMORYERR;
  70.     return PROCERR_FALSE;
  71.    }
  72.    //填写图像信息
  73.    lpProcInfo->dImageInfo.width=w;
  74.    lpProcInfo->dImageInfo.height=h;
  75.    lpProcInfo->pdLineAddr=(unsigned long**)New(lpProcInfo->dImageInfo.height*sizeof(long));
  76.    if(lpProcInfo->pdLineAddr==NULL)
  77.    {
  78. // Add by YZ 2000-9-22 增加了释放上面那个内存块的代码
  79. lpProcInfo->_pdbdata = Del(lpProcInfo->_pdbdata);
  80.     lpProcInfo->result=PR_MEMORYERR;
  81.     return PROCERR_FALSE;
  82.    }
  83.    lpProcInfo->dImageInfo.bitperpix=lpProcInfo->sImageInfo.bitperpix;
  84.    lpProcInfo->dImageInfo.bAlpha=lpProcInfo->sImageInfo.bAlpha;
  85.    // YZ Modify 2000-9-22 因为图像处理模块将始终工作在32位位图格式,所以
  86.    // 下面的几行可不要。
  87.    //int bpl=w*(lpProcInfo->sImageInfo.bitperpix/8);
  88.    //bpl=bpl%4==0?bpl:(bpl/4+1)*4;
  89.    //lpProcInfo->dImageInfo.byteperline=bpl;
  90.    lpProcInfo->dImageInfo.byteperline=lpProcInfo->dImageInfo.width*4;
  91. // YZ Modify 2000-9-22 下面原来的那行代码的计算方式有误,因为ISee内部
  92.    // 标准图像格式是倒向的DIB(lpProcInfo->dImageInfo.height的值是一个正值),
  93.    // 所以,第一行的地址应该在位缓冲的末尾。
  94.    for(int i=0;i<lpProcInfo->dImageInfo.height;i++)
  95.     lpProcInfo->pdLineAddr[i]=(unsigned long*)(lpProcInfo->_pdbdata+((lpProcInfo->dImageInfo.height-i-1)*(lpProcInfo->dImageInfo.width*4)));
  96.     //lpProcInfo->pdLineAddr[i]=(unsigned long*)lpProcInfo->_pdbdata+lpProcInfo->dImageInfo.byteperline*i;
  97. switch(rs_flag)
  98.    {
  99.     case RS_STRETCH:
  100.       {
  101.          int r=Output_Resize(w,h,lpProcInfo->_pdbdata);
  102.          if(r)
  103.          {
  104.        lpProcInfo->result=PR_SUCCESS;
  105.     return PROCERR_SUCCESS;
  106.          }
  107.          else
  108.           return r;
  109.       }
  110.       case RS_TILE:
  111.        return Output_ResizeTile(w,h,lpProcInfo->_pdbdata);
  112.       case RS_CENTER:
  113. return Output_ResizePos(w,h,lpProcInfo->_pdbdata,RS_CENTER,&rs_bgcolor);
  114.       case RS_KEEP:
  115. return Output_ResizePos(w,h,lpProcInfo->_pdbdata,rs_pos,&rs_bgcolor);
  116.    }
  117.    return FALSE;
  118. }
  119. //平铺
  120. int Output_ResizeTile(int width,int height,LPBYTE lpDestData)
  121. {
  122. LPBYTE lpsData=(LPBYTE)lpProcInfo->_psbdata,lpBak,lpBako;
  123.    LPBYTE lpdData=lpDestData;
  124.    if(lpDestData==NULL )
  125.     return PROCERR_FALSE;
  126.    int skip = lpProcInfo->sImageInfo.bitperpix/8;
  127.    int x=lpProcInfo->sImageInfo.width;
  128.    int y=lpProcInfo->sImageInfo.height;
  129.    int wc=0,hc=0;
  130.    lpsData+=x*(y-1)*skip;
  131.    lpdData+=width*(height-1)*skip;
  132.    lpBako=lpBak=lpsData;
  133.    for(int j=0;j<height;j++)
  134.    {
  135. for(int i=0;i<width;i++)
  136.       {
  137.          for(int k=0;k<skip;k++)
  138.          {
  139.             *lpdData=*lpsData;
  140.             lpdData++;
  141.             lpsData++;
  142.          }
  143.          wc++;
  144.          if(wc>=x)
  145.          {
  146.           wc=0;
  147.           lpsData=lpBak;
  148.          }
  149.       }
  150.       wc=0;
  151.       lpBak-=(x*skip);
  152.       lpdData-=(width*skip*2);
  153.       hc++;
  154.       if(hc>=y)
  155.       {
  156.        hc=0;
  157.        lpBak=lpBako;
  158.       }
  159. lpsData=lpBak;
  160.    }
  161.    lpProcInfo->result=PR_SUCCESS;
  162. return PROCERR_SUCCESS;
  163. }
  164. //保持图像(包括居中)
  165. int Output_ResizePos(int w,int h,LPBYTE lpDestData,int rs_pos,COLORREF* rs_bgcolor)
  166. {
  167. LPBYTE lpsData=(LPBYTE)lpProcInfo->_psbdata,lpBak;
  168.    LPBYTE lpdData=lpDestData,lpColor=(LPBYTE)rs_bgcolor;
  169.    if(lpDestData==NULL )
  170.     return PROCERR_FALSE;
  171.    int skip = lpProcInfo->sImageInfo.bitperpix/8;
  172.    int x=lpProcInfo->sImageInfo.width;
  173.    int y=lpProcInfo->sImageInfo.height;
  174.    int xPos,yPos,xt,yt;
  175.    switch(rs_pos)
  176.    {
  177.     case RS_UL:
  178.        xPos=0;
  179.          yPos=0;
  180.          break;
  181.       case RS_UM:
  182.        xPos=(w-x)/2;
  183.          yPos=0;
  184.          break;
  185.       case RS_UR:
  186.        xPos=w-x;
  187.          yPos=0;
  188.          break;
  189.       case RS_ML:
  190.        xPos=0;
  191.          yPos=(h-y)/2;
  192.          break;
  193.       case RS_CENTER:
  194.       case RS_MM:
  195.        xPos=(w-x)/2;
  196.          yPos=(h-y)/2;
  197.          break;
  198.       case RS_MR:
  199.        xPos=w-x;
  200.          yPos=(h-y)/2;
  201.          break;
  202. case RS_DL:
  203.        xPos=0;
  204.          yPos=h-y;
  205.          break;
  206.       case RS_DM:
  207.        xPos=(w-x)/2;
  208.          yPos=h-y;
  209.          break;
  210.       case RS_DR:
  211.        xPos=w-x;
  212.          yPos=h-y;
  213.          break;
  214.    }
  215.    int wc=0,hc=0;
  216.    if(xPos<0)
  217.     xt=xPos;
  218.    else
  219.     xt=0;
  220.    if(yPos<0)
  221.     yt=yPos;
  222.    else
  223.     yt=0;
  224.    lpsData+=(x*(y+yt-1)-xt)*skip; //根据xPos,yPos计算源图像绘制区域原点位置(如果是缩小图像),否则原点为(0,0)(窗口显示坐标,原点在左上角)
  225.    lpdData+=w*(h-1)*skip;
  226.    lpBak=lpsData;
  227.    for(int j=0;j<h;j++)
  228.    {
  229.       if(j<yPos && yt==0) //填充背景色
  230.       {
  231.        for(int k=0;k<w;k++)
  232.          {
  233.           *lpdData=lpColor[2];  //blue
  234.             lpdData++;
  235.             *lpdData=lpColor[1];
  236.             lpdData++;
  237.             *lpdData=lpColor[0];
  238.             lpdData++;
  239.             *lpdData=lpColor[3];
  240.             lpdData++;
  241.          }
  242.          lpdData-=(w*skip*2);
  243.       }
  244.       else
  245.       {
  246. for(int i=0;i<w;i++)
  247.        {
  248.           if(i<xPos && xt==0)
  249.           {
  250.              *lpdData=lpColor[2];
  251.             lpdData++;
  252.              *lpdData=lpColor[1];
  253.              lpdData++;
  254.              *lpdData=lpColor[0];
  255.              lpdData++;
  256.             *lpdData=lpColor[3];
  257.              lpdData++;
  258.             }
  259.             else
  260.          {
  261.              wc++;
  262.           if(wc>x)
  263.          {
  264.            *lpdData=lpColor[2];
  265.              lpdData++;
  266.              *lpdData=lpColor[1];
  267.              lpdData++;
  268.               *lpdData=lpColor[0];
  269.              lpdData++;
  270.              *lpdData=lpColor[3];
  271.              lpdData++;
  272.          }
  273.                else
  274.                 for(int m=0;m<skip;m++)
  275.          {
  276.              *lpdData=*lpsData;
  277.               lpdData++;
  278.              lpsData++;
  279.           }
  280.             }
  281.        }
  282.          wc=0;
  283.          hc++;
  284.          if(hc>=y)
  285.          {
  286.           //条件成立,则以后只填充背景色,设置yPos,yt使填充背景色条件永远成立
  287.           yPos=h;
  288.             yt=0;
  289.          }
  290.          lpdData-=(w*skip*2);
  291.          lpBak-=(x*skip);
  292.          lpsData=lpBak;
  293.       }
  294.    }
  295.    lpProcInfo->result=PR_SUCCESS;
  296. return PROCERR_SUCCESS;
  297. }