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

图形图象

开发平台:

Visual C++

  1. /********************************************************************
  2. rotate.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 "draw.h"
  30. #include "rotate.h"
  31. #include "resource.h"
  32. #define UL 0x00 //原图像左上角旋转后在左上角
  33. #define DL 0x40        //原图像左上角旋转后在左下角
  34. #define DR 0x80        //原图像左上角旋转后在右下角
  35. #define UR 0xc0        //原图像左上角旋转后在右上角
  36. LPVOID lpPreViewData=NULL,lpBakData=NULL;
  37. int prev_width,prev_height,mem_size;
  38. RECT rt;
  39. extern HBITMAP hbm;
  40. BOOL bRotate=FALSE; //图像是否旋转标志(即图像宽高是否调换)
  41. BYTE pos=UL;            //原图像左上角旋转后位置
  42. void Out_Rotate();
  43. void Out_Flip();
  44. //绘制预览图像
  45. void DrawPreView(HWND hWnd,LPDRAWITEMSTRUCT lpInfo)
  46. {
  47.    //绘制背景
  48.    HDC hmemdc;
  49.    hmemdc=CreateCompatibleDC(lpInfo->hDC);
  50.    // YZ Modify 2000-8-15 适当恢复DC中的单色位图
  51.    HBITMAP hOldBmp = (HBITMAP)SelectObject(hmemdc,hbm);
  52.    //SelectObject(hmemdc,hbm);
  53.    for(int j=0;j<lpInfo->rcItem.bottom;j+=48)
  54.       for(int i=0;i<lpInfo->rcItem.right;i+=48)
  55.          BitBlt(lpInfo->hDC,i,j,48,48,hmemdc,0,0,SRCCOPY);
  56.    SelectObject(hmemdc, hOldBmp);
  57.    DeleteDC(hmemdc);
  58.    float x,y;
  59. if(lpPreViewData==NULL)
  60.    {
  61.     lpPreViewData=(LPVOID)lpProcInfo->_psbdata;
  62.       if(lpPreViewData==NULL)
  63.        return;
  64.       //求预览图片尺寸
  65.       int rcw=lpInfo->rcItem.right-lpInfo->rcItem.left;
  66.       int rch=lpInfo->rcItem.bottom-lpInfo->rcItem.top;
  67.       x=(float)lpProcInfo->sImageInfo.width;
  68.       y=(float)lpProcInfo->sImageInfo.height;
  69.       if(lpProcInfo->sImageInfo.width > rcw || lpProcInfo->sImageInfo.height > rch)
  70.       {
  71.        if(lpProcInfo->sImageInfo.width >= lpProcInfo->sImageInfo.height)
  72. {
  73.         prev_width=rcw;
  74.           x=y/x;
  75.           x=x*prev_width;
  76.             if(x<8)
  77.              x=8;
  78.          prev_height=(int)x;
  79.           rt.left=0;
  80.           rt.top=(prev_width-prev_height)/2;
  81.           rt.right=prev_width;
  82.          rt.bottom=rt.top+prev_height;
  83.        }
  84.        else
  85.       {
  86.           prev_height=rch;
  87.           x=x/y;
  88.           x=x*prev_height;
  89.             if(x<8)
  90.              x=8;
  91.          prev_width=(int)x;
  92.           rt.left=(prev_height-prev_width)/2;
  93.           rt.top=0;
  94.           rt.right=rt.left+prev_width;
  95.          rt.bottom=prev_height;
  96.        }
  97.       }
  98.       else
  99.       {
  100.        prev_width=lpProcInfo->sImageInfo.width;
  101.          prev_height=lpProcInfo->sImageInfo.height;
  102.          rt.left=(rcw-prev_width)/2;
  103.          rt.top=(rch-prev_height)/2;
  104.          rt.right=rt.left+prev_width;
  105.          rt.bottom=rt.top+prev_height;
  106.       }
  107.    //创建prev_width*prev_height内存图像
  108.       mem_size=prev_width*prev_height*(lpProcInfo->sImageInfo.bitperpix/8);
  109.     LPVOID lptemp=New(mem_size);
  110.       lpBakData=New(mem_size);
  111.    if(lptemp==NULL || lpBakData==NULL)
  112.     {
  113.        // YZ Modify 2000-8-15 安全第一:-)
  114.          if (lptemp) lptemp=Del(lptemp);
  115.          if (lpBakData) lpBakData=Del(lpBakData);
  116.     lpProcInfo->result=PR_MEMORYERR;
  117.       SendMessage(hWnd,WM_CLOSE,0,0);
  118.        return;
  119.    }
  120.       //生成预览图像
  121. Output_Resize(prev_width,prev_height,(LPBYTE)lptemp);
  122.     lpPreViewData = lptemp;
  123.       CopyMemory(lpBakData,lpPreViewData,mem_size);
  124.    }
  125.    DoDlgDraw(lpInfo->hDC,&rt,prev_width,prev_height,lpPreViewData);
  126. }
  127. //预览图像向左旋转90度
  128. void TurnLeft()
  129. {
  130. if(lpPreViewData==NULL)
  131.     return;
  132.    int temp;
  133.    temp=rt.top;
  134.    rt.top=rt.left;
  135.    rt.left=temp;
  136.    temp=rt.right;
  137.    rt.right=rt.bottom;
  138.    rt.bottom=temp;
  139.    temp=prev_width;
  140.    prev_width=prev_height;
  141.    prev_height=temp;
  142. //标记图像已旋转,记录原图像左上角旋转后位置
  143.    bRotate = !bRotate;
  144.    pos = (BYTE)(pos+0x40);
  145. //prev_width与prev_height已调换,所以以下编程请注意:新图像宽高不调换,旧图像调换
  146. int skip = lpProcInfo->sImageInfo.bitperpix/8;
  147. LPBYTE lpData=(LPBYTE)lpBakData;
  148.    int new_width=prev_width*(lpProcInfo->sImageInfo.bitperpix/8);
  149.    LPBYTE lpDest=(LPBYTE)lpPreViewData+new_width-skip,lpBak=lpDest;
  150. for(int j=1;j<=prev_width;j++)
  151.    {
  152.     for(int i=0;i<prev_height;i++)
  153.       {
  154.        for(int k=0;k<skip;k++)
  155.          {
  156.           *lpDest=*lpData;
  157.             lpDest++;
  158.             lpData++;
  159.          }
  160.          lpDest+=(new_width-skip);
  161.       }
  162.       lpBak-=skip;
  163.       lpDest=lpBak;
  164.    }
  165.    CopyMemory(lpBakData,lpPreViewData,mem_size);
  166. }
  167. //预览图像向右旋转90度
  168. void TurnRight()
  169. {
  170. if(lpPreViewData==NULL)
  171.     return;
  172.    int temp;
  173.    temp=rt.top;
  174.    rt.top=rt.left;
  175.    rt.left=temp;
  176.    temp=rt.right;
  177.    rt.right=rt.bottom;
  178.    rt.bottom=temp;
  179.    temp=prev_width;
  180.    prev_width=prev_height;
  181.    prev_height=temp;
  182.    bRotate = !bRotate;
  183.    pos = (BYTE)(pos-0x40);
  184. int skip = lpProcInfo->sImageInfo.bitperpix/8;
  185. LPBYTE lpData=(LPBYTE)lpBakData;
  186.    int new_width=prev_width*(lpProcInfo->sImageInfo.bitperpix/8);
  187.    LPBYTE lpDest=(LPBYTE)lpPreViewData+new_width*(prev_height-1),lpBak=lpDest;
  188. for(int j=1;j<=prev_width;j++)
  189.    {
  190.     for(int i=0;i<prev_height;i++)
  191.       {
  192.        for(int k=0;k<skip;k++)
  193.          {
  194.           *lpDest=*lpData;
  195.             lpDest++;
  196.             lpData++;
  197.          }
  198.          lpDest-=(new_width+skip);
  199.       }
  200.       lpBak+=skip;
  201.       lpDest=lpBak;
  202.    }
  203.    CopyMemory(lpBakData,lpPreViewData,mem_size);
  204. }
  205. //预览图像横向反转
  206. void HFlip()
  207. {
  208. if(lpPreViewData==NULL)
  209.     return;
  210.    pos ^= 0xc0;
  211. int skip = lpProcInfo->sImageInfo.bitperpix/8;
  212.    int width=prev_width*skip;
  213.    LPBYTE lpData=(LPBYTE)lpBakData;
  214.    LPBYTE lpDest=(LPBYTE)lpPreViewData+width-skip;
  215.    int width_plus=skip<<1;
  216.    int height_plus=width<<1;
  217.    for(int j=0;j<prev_height;j++)
  218.    {
  219.     for(int i=0;i<prev_width;i++)
  220.       {
  221.        for(int k=0;k<skip;k++)
  222.          {
  223.           *lpDest=*lpData;
  224.             lpDest++;
  225.             lpData++;
  226.          }
  227.          lpDest-=width_plus;
  228.       }
  229.       lpDest+=height_plus;
  230.    }
  231.    CopyMemory(lpBakData,lpPreViewData,mem_size);
  232. }
  233. //预览图像纵向反转
  234. void VFlip()
  235. {
  236. if(lpPreViewData==NULL)
  237.     return;
  238.    pos ^= 0x40;
  239. int width=prev_width*(lpProcInfo->sImageInfo.bitperpix/8);
  240.    LPBYTE lpData=(LPBYTE)lpBakData;
  241.    LPBYTE lpDest=(LPBYTE)lpPreViewData+width*(prev_height-1);
  242.    int height_plus=width<<1;
  243.    for(int j=0;j<prev_height;j++)
  244.    {
  245.     for(int i=0;i<width;i++)
  246.       {
  247.        *lpDest=*lpData;
  248.          lpDest++;
  249.          lpData++;
  250.       }
  251.       lpDest-=height_plus;
  252.    }
  253.    CopyMemory(lpBakData,lpPreViewData,mem_size);
  254. }
  255. //实际图像旋转处理
  256. int Output_Rotate()
  257. {
  258. //创建内存图像
  259.    lpProcInfo->_pdbdata = (unsigned char*)New(lpProcInfo->sImageInfo.width*lpProcInfo->sImageInfo.height*(lpProcInfo->sImageInfo.bitperpix/8));
  260.    if(lpProcInfo->_pdbdata==NULL)
  261.    {
  262.     lpProcInfo->result=PR_MEMORYERR;
  263.     return PROCERR_FALSE;
  264.    }
  265.    //填写旋转后图像信息
  266.    if(bRotate)
  267.    {
  268. lpProcInfo->dImageInfo.width=lpProcInfo->sImageInfo.height;
  269.       lpProcInfo->dImageInfo.height=lpProcInfo->sImageInfo.width;
  270.    }
  271.    else
  272.    {
  273. lpProcInfo->dImageInfo.width=lpProcInfo->sImageInfo.width;
  274.       lpProcInfo->dImageInfo.height=lpProcInfo->sImageInfo.height;
  275.    }
  276.    lpProcInfo->pdLineAddr=(unsigned long**)New(lpProcInfo->dImageInfo.height*sizeof(long));
  277.    if(lpProcInfo->pdLineAddr==NULL)
  278.    {
  279.     // YZ Modify 2000-8-15 增加了释放上面那个内存块的代码
  280.       lpProcInfo->_pdbdata = Del(lpProcInfo->_pdbdata);
  281.     lpProcInfo->result=PR_MEMORYERR;
  282.     return PROCERR_FALSE;
  283.    }
  284.    lpProcInfo->dImageInfo.bitperpix=lpProcInfo->sImageInfo.bitperpix;
  285.    lpProcInfo->dImageInfo.bAlpha=lpProcInfo->sImageInfo.bAlpha;
  286.    // YZ Modify 2000-8-15 因为图像处理模块将始终工作在32位位图格式,所以
  287.    // 下面的几行可不要。
  288.    //int bpl=lpProcInfo->dImageInfo.width*(lpProcInfo->sImageInfo.bitperpix/8);
  289.    //bpl=bpl%4==0?bpl:(bpl/4+1)*4;
  290.    //lpProcInfo->dImageInfo.byteperline=bpl;
  291.    lpProcInfo->dImageInfo.byteperline=lpProcInfo->dImageInfo.width*4;
  292. // YZ Modify 2000-8-15 下面原来的那行代码的计算方式有误,因为ISee内部
  293.    // 标准图像格式是倒向的DIB(lpProcInfo->dImageInfo.height的值是一个正值),
  294.    // 所以,第一行的地址应该在位缓冲的末尾。
  295.    for(int i=0;i<lpProcInfo->dImageInfo.height;i++)
  296.       lpProcInfo->pdLineAddr[i]=(unsigned long*)(lpProcInfo->_pdbdata+((lpProcInfo->dImageInfo.height-i-1)*(lpProcInfo->dImageInfo.width*4)));
  297.     //lpProcInfo->pdLineAddr[i]=(unsigned long*)lpProcInfo->_pdbdata+lpProcInfo->dImageInfo.byteperline*i;
  298. //根据图像旋转标志做相应处理
  299.    if(bRotate)
  300.     Out_Rotate();
  301.    else
  302.     Out_Flip();
  303.    lpProcInfo->result=PR_SUCCESS;
  304.    return PROCERR_SUCCESS;
  305. }
  306. //图像宽高已调换,做旋转处理
  307. void Out_Rotate()
  308. {
  309. int skip = lpProcInfo->sImageInfo.bitperpix/8;
  310. LPBYTE lpData=(LPBYTE)lpProcInfo->_psbdata;
  311.    int new_width=lpProcInfo->dImageInfo.width*skip;
  312.    LPBYTE lpDest;
  313.    int width_plus,height_plus;
  314.    switch(pos)
  315.    {
  316.     case UL:        //图像向左旋转90度后上下反转
  317.     lpDest=(LPBYTE)lpProcInfo->_pdbdata+new_width*lpProcInfo->dImageInfo.height-skip;
  318.          width_plus=-new_width-skip;
  319.          height_plus=-skip;
  320.          break;
  321.       case DL:        //图像向左旋转90度
  322.          lpDest=(LPBYTE)lpProcInfo->_pdbdata+new_width-skip;
  323.          width_plus=new_width-skip;
  324.          height_plus=-skip;
  325.          break;
  326.       case DR:        //图像向右旋转90度后上下反转
  327.          lpDest=(LPBYTE)lpProcInfo->_pdbdata;
  328.          width_plus=new_width-skip;
  329.          height_plus=skip;
  330.          break;
  331.       case UR:        //图像向右旋转90度
  332.          lpDest=(LPBYTE)lpProcInfo->_pdbdata+new_width*(lpProcInfo->dImageInfo.height-1);
  333.          width_plus=-new_width-skip;
  334.          height_plus=skip;
  335.          break;
  336.    }
  337.    LPBYTE lpBak=lpDest;
  338. for(int j=0;j<lpProcInfo->sImageInfo.height;j++)
  339.    {
  340.     for(int i=0;i<lpProcInfo->sImageInfo.width;i++)
  341.       {
  342.        for(int k=0;k<skip;k++)
  343.          {
  344.           *lpDest=*lpData;
  345.             lpDest++;
  346.             lpData++;
  347.          }
  348.          lpDest+=width_plus;
  349.       }
  350.       lpBak+=height_plus;
  351.       lpDest=lpBak;
  352.    }
  353. }
  354. //图像宽高未调换,做反转处理
  355. void Out_Flip()
  356. {
  357. int skip = lpProcInfo->sImageInfo.bitperpix/8;
  358. LPBYTE lpData=(LPBYTE)lpProcInfo->_psbdata;
  359.    int width=lpProcInfo->sImageInfo.width*skip;
  360.    LPBYTE lpDest;
  361.    int width_plus,height_plus;
  362.    switch(pos)
  363.    {
  364.       case UL:        //与原图像相同,直接COPY图像数据
  365.        CopyMemory(lpProcInfo->_pdbdata,lpProcInfo->_psbdata,lpProcInfo->sImageInfo.width*lpProcInfo->sImageInfo.height*(lpProcInfo->sImageInfo.bitperpix/8));
  366.          return;
  367.     case DL:        //图像上下反转
  368.          lpDest=(LPBYTE)lpProcInfo->_pdbdata+width*(lpProcInfo->dImageInfo.height-1);
  369.          width_plus=0;
  370.          height_plus=-(width<<1);
  371.          break;
  372.       case DR:        //图像旋转180度
  373.          lpDest=(LPBYTE)lpProcInfo->_pdbdata+width*lpProcInfo->dImageInfo.height-skip;
  374.          width_plus=-(skip<<1);
  375.          height_plus=0;
  376.          break;
  377.       case UR:        //图像左右反转
  378.          lpDest=(LPBYTE)lpProcInfo->_pdbdata+width-skip;
  379.          width_plus=-(skip<<1);
  380.          height_plus=width<<1;
  381.          break;
  382.    }
  383.    for(int j=0;j<lpProcInfo->sImageInfo.height;j++)
  384.    {
  385.     for(int i=0;i<lpProcInfo->sImageInfo.width;i++)
  386.       {
  387.          for(int k=0;k<skip;k++)
  388.          {
  389.        *lpDest=*lpData;
  390.           lpDest++;
  391.             lpData++;
  392.          }
  393.          lpDest+=width_plus;
  394.       }
  395.       lpDest+=height_plus;
  396.    }
  397. }