CHandleImage 自己写的用GDI+处理图像的一个类

来源:互联网 发布:奢侈品品牌 知乎 编辑:程序博客网 时间:2024/06/14 04:15

 

  该类可以实现的功能:

          在图像上选定某一矩形区域并查看

          使用左右方向键调整矩形区域大小,使用向下方向键重新生成一个矩形区域

          鼠标点击某区域,可以查看此区域内的图像

          删除建立好的区域等

 

.H文件

class CHandleImage{public:CHandleImage();~CHandleImage();public:Graphics *m_pGraphics1;  //橡皮筋1中的图片Graphics *m_pGraphics2; //橡皮筋2中的图片Bitmap *m_pImageObj;// 拖放图像CPoint m_pt;//CSize m_size;BOOL m_bcapture;CSize m_offsetsize;// 保存鼠标按下时那一瞬间的cpoint 和 大小CPoint m_btDownPoint; //图片左上角坐标CSize  m_btDownSize;  //图片初始大小CRectTracker  m_RectTracker1;  //橡皮筋1CRectTracker  m_RectTracker2;  //橡皮筋2CRectTracker  m_unitTracker;   // 分块处理时的橡皮筋//............ 锁定图片BOOL m_bLock;//锁定图片BOOL m_bLook;// 是否查看BOOL m_bleftDown;BOOL m_bleftUp;CPoint m_leftBnDown;CPoint m_movePoint;//........ 锁定区域  struct CRectTracker_Lock {CRectTracker_Lock() {radio_distance_x=0;radio_distance_y=0;radio_width=0;radio_height=0;next=NULL;bSelected=FALSE;};CRectTracker  rectLock;   // 要处理图像区域为橡皮筋  视图坐标系double radio_distance_x;  // 矩形相对于图像左侧的比率 double radio_distance_y;  // 矩形相对于图像上端的比率double radio_width;       // 矩形相对于图像宽度的比率double radio_height;      // 矩形相对于图像高度的比率   // 这四个比率用以确定矩形在图像中的位置CRectTracker_Lock * next; // 下一个区域BOOL  bSelected;          // 是否被选定} ;    CRectTracker_Lock * headRectTraker;BOOL m_moving;BOOL m_berase;BOOL m_becapture2;//是否捕获第二个图片double m_step;BOOL m_isKeyMoving;BOOL m_bControlUnit;CRectTracker_Lock * headRectTrakerOnUnit;  // 分块处理时,所画矩形链表的头结点BOOL m_bFixedColumn; //固定行列PointF m_p1,m_p2; // 新Line的始末坐标点double m_stepRight;//按方向键时 向右移动的步长CPoint m_offPt;int m_width_w;int m_height_h;void DrawRectLock();           //  画已经建立好的所有矩形区域 坐标系为视图坐标系 //  以位图为绘图设备上下文 (如:Graphics *pG=new Graphics(&bmp); m_handleImage.m_pGraphics1=pG;)pt为此位图绘制到视图中时,相对于视图(0,0)点的偏移 (也即位图绘制在视图中的左上角坐标)// graphics.DrawImage(&bmp,m_ClientRect.left,m_ClientRect.top,m_ClientRect.Width(),m_ClientRect.Height()); //  m_ClientRect.TopLeft()即为ptvoid DrawRectLock(CPoint pt); void DrawRectLockInFenKuai(CPoint pt,CRect sourceRc,BOOL bFenKuai);  // 画分块的所有矩形   sourceRc为分块在原图中的位置  bFenKuai  是否录入分块BOOL RectInFenKuai(CRectTracker_Lock *p,CRect souceRc);void DrawLine(PointF p1,PointF p2);  // 画列右边的向下箭头, 用以确定列的范围   void DrawLine(PointF p1,PointF p2,CPoint p3);  //p3为偏移量  当位图为绘图设备上下文时,当将位图绘制在视图中时,位图左上角坐标;//选定区域同步移动void GetTheRadio(CRectTracker_Lock *q); // 根据q的矩形大小 获得q相对于原图的比率 void DrawTheRect(CRectTracker_Lock* q); // 画单个矩形void DrawTheRect(CRectTracker_Lock* q,CPoint pt);void DrawTheRect(CRectTracker_Lock* q,CPoint pt,BOOL bFirst); //bFirst指定是否为第一个要查看的区域void DrawRectImage(CRectTracker_Lock *q);  //在m_pGraphics1上画q矩形区域void AdjustRect(CRectTracker_Lock* q);// 重新调整矩形大小, 否则,移动后, 判断是否在矩形内 会出现问题void AdjustAllRect();// 重新调整所有矩形// 在另一个PICTURE控件上画图void GetRectImage(CRectTracker_Lock *q, RectF &rect);  //获得选定区域的图片起始点和宽带高度等信息void  DrawRectImageOnImageOne(CRect &rect); //在m_image上覆盖掉原图  实时画矩形又能防止闪烁   屏幕显示图像的大小为实时矩形的大小//分块处理void DrawUnitImageOnImageOne(CRect &rect);  // 在Image1上画分块的图像, 屏幕显示图像的大小为原图中的大小  void DrawRectImageOnUnit(CRect  &rect);  // 分块处理时,在分块区域上画实时矩形 void GetTheRadioOnUnit(CRectTracker_Lock *q);void GetUnitRectImageInfo(CRectTracker_Lock *q, RectF &souce_imageRectF);//分块处理时获得矩形区域中原图片的坐标位置,以图片的左上角为(0,0)点void DrawTheRectOnUnit(CRectTracker_Lock* q);void DrawRectImageFromUnitOnImageOne(CRect &rect); //分块处理时 在image1上画矩形中的图像void AdjustRectOnUnit(CRectTracker_Lock* q);  // 察除区域时,当橡皮筋移动时,实时记录橡皮筋中的矩形区域位置//新建节点void NewNode();void NewNode(const CRect& rc,double radio_distance_x,double radio_distance_y,double radio_width,double radio_height);// 根据整图位置rect 已经比率,确定节点矩形的位置      void NewNode(double radio_distance_x,double radio_distance_y,double radio_width,double radio_height);// 根据比率,建立节点  然后再通过整图位置,调整节点void CHandleImage::NewNodeTail(double radio_distance_x,double radio_distance_y,double radio_width,double radio_height);// 新加结点作为尾结点void AdjustNode(CRect & rc,CRectTracker_Lock *p);// 调整上面根据比率所建立的节点void AdjuctAllNodes(CRect & rc); //调整所有根据比率所建立的节点//察除节点void Erase(CPoint point); //若point在矩形中,则将此矩形节点删除void EraseAll();                                                                                                                                             void EraseNodesInRect(CRect rect); // 删除与矩形Rect相交的节点  rect为矩形在原始图片中的位置(原始图片左上角为(0,0)点)//查看节点void Look(CPoint point);  //查看某矩形区域CRectTracker_Lock * FindFirstToLook()  {CRectTracker_Lock * p=headRectTraker;while(p!=NULL){if (p->bSelected)return p;p=p->next;}return NULL;};void LookLeft() //查看当前位置左边的区域{CRectTracker_Lock * p=headRectTraker;CRectTracker_Lock * pre=NULL;while(p!=NULL){if (p->bSelected) // 指定的节点break;pre=p;p=p->next;}if (pre!=NULL) //找到指定节点的前一个节点了pre->bSelected=TRUE;}void LookRight(){        CRectTracker_Lock * pF=FindFirstToLook();if(headRectTraker!=NULL&&pF==NULL)headRectTraker->bSelected=TRUE;else{if (pF->next!=NULL){pF->bSelected=FALSE;pF->next->bSelected=TRUE;}}}//线条往左移void LineMoveLeft(unsigned int i);   //响应左方向键void LineMoveRight(unsigned int i);  //响应右方向键// 按向下方向键时,生成一个新的节点void KeyDownToCreateOneNode();       //响应向下方向键void ReSetLinePos();//CPoint AdjustTracker(CRect clientRect);  // rect为 橡皮筋所在的绘图环境客户端区域};


.cpp文件

 

#include "stdafx.h"#include "HandleImage.h"CHandleImage::CHandleImage(){m_bcapture=FALSE;m_pt.x=0;m_pt.y=0;//m_size=10;//m_size=10;m_offsetsize.cx=0;m_offsetsize.cy=0;m_bLock=FALSE;m_bLook=FALSE;m_bleftDown=FALSE;  m_bleftUp=FALSE;m_movePoint.x=m_movePoint.y=0;m_leftBnDown.x=m_leftBnDown.y=0;m_btDownPoint.x=m_btDownPoint.y=0;m_RectTracker2.m_nStyle=CRectTracker::resizeOutside|CRectTracker::dottedLine;m_RectTracker1.m_nHandleSize=3;m_RectTracker2.m_nHandleSize=3;m_RectTracker1.m_rect.SetRectEmpty();m_RectTracker2.m_rect.SetRectEmpty();// 锁定区域headRectTraker=NULL;m_moving=FALSE;m_berase=FALSE;m_becapture2=FALSE;m_step=0;m_isKeyMoving=FALSE;m_bControlUnit=FALSE; //分块处理m_unitTracker.m_rect.SetRectEmpty();headRectTrakerOnUnit=NULL;//m_bFixedColumn=TRUE;m_p1.X=m_p2.X=0;m_p1.Y=m_p2.Y=0;m_stepRight=0;m_width_w=0;m_height_h=0;m_offPt.x=m_offPt.y=0;m_pGraphics1=m_pGraphics2=NULL;m_pImageObj=NULL;}CHandleImage::~CHandleImage(){CRectTracker_Lock *p=headRectTraker;while(p!=NULL){headRectTraker=p->next;delete p;p=headRectTraker;}    headRectTraker=NULL;CRectTracker_Lock *pUnit=headRectTrakerOnUnit;while(pUnit!=NULL){headRectTrakerOnUnit=pUnit->next;delete pUnit;pUnit=headRectTrakerOnUnit;}headRectTrakerOnUnit=NULL;/*if(m_pImageObj!=NULL){delete  m_pImageObj;m_pImageObj=NULL;}*//*if (m_pGraphics1!=NULL){delete m_pGraphics1;m_pGraphics1=NULL;}*/if (m_pGraphics2!=NULL){delete m_pGraphics2;m_pGraphics2=NULL;}}void CHandleImage::AdjustRect(CRectTracker_Lock* q){q->rectLock.m_rect.TopLeft().x=m_RectTracker1.m_rect.TopLeft().x+q->radio_distance_x*m_RectTracker1.m_rect.Width();q->rectLock.m_rect.TopLeft().y=m_RectTracker1.m_rect.TopLeft().y+q->radio_distance_y*m_RectTracker1.m_rect.Height();q->rectLock.m_rect.BottomRight().x=q->rectLock.m_rect.TopLeft().x+q->radio_width*m_RectTracker1.m_rect.Width();q->rectLock.m_rect.BottomRight().y=q->rectLock.m_rect.TopLeft().y+q->radio_height*m_RectTracker1.m_rect.Height();}void CHandleImage::AdjustAllRect(){CRectTracker_Lock *p=headRectTraker;while(p!=NULL){AdjustRect(p);p=p->next;}}void CHandleImage::AdjustRectOnUnit(CRectTracker_Lock* q){q->rectLock.m_rect.TopLeft().x=m_unitTracker.m_rect.TopLeft().x+q->radio_distance_x*m_unitTracker.m_rect.Width();q->rectLock.m_rect.TopLeft().y=m_unitTracker.m_rect.TopLeft().y+q->radio_distance_y*m_unitTracker.m_rect.Height();q->rectLock.m_rect.BottomRight().x=q->rectLock.m_rect.TopLeft().x+q->radio_width*m_unitTracker.m_rect.Width();q->rectLock.m_rect.BottomRight().y=q->rectLock.m_rect.TopLeft().y+q->radio_height*m_unitTracker.m_rect.Height();}void CHandleImage::DrawLine(PointF p1,PointF p2){Pen pen(Color(255,255,0,0),2);m_pGraphics1->DrawLine(&pen,p1,p2);}void CHandleImage::DrawLine(PointF p1,PointF p2,CPoint p3){Pen pen(Color(255,255,0,0),2);p1.X-=p3.x;p1.Y-=p3.y;p2.X-=p3.x;p2.Y-=p3.y;m_pGraphics1->DrawLine(&pen,p1,p2);}void CHandleImage::DrawRectImage(CRectTracker_Lock *q) // 在m_image2上画图片{RectF souce_imageRectF;GetRectImage(q,souce_imageRectF);CRect rect2;rect2=m_RectTracker2.m_rect;RectF rect2Des;rect2Des.X=rect2.TopLeft().x;rect2Des.Y=rect2.TopLeft().y;rect2Des.Width=rect2.Width();rect2Des.Height=rect2.Height();//----------m_pGraphics1->DrawImage(m_pImageObj,rect2Des,souce_imageRectF.X,souce_imageRectF.Y,souce_imageRectF.Width,souce_imageRectF.Height,UnitPixel);}void CHandleImage::DrawRectImageFromUnitOnImageOne(CRect &rect){RectF souce_imageRectF;GetUnitRectImageInfo(headRectTrakerOnUnit,souce_imageRectF);CRect rect2;rect2=m_RectTracker2.m_rect;RectF rect2Des;rect2Des.X=rect2.TopLeft().x;rect2Des.Y=rect2.TopLeft().y;rect2Des.Width=rect2.Width();rect2Des.Height=rect2.Height();m_pGraphics2->DrawImage(m_pImageObj,rect2Des,souce_imageRectF.X,souce_imageRectF.Y,souce_imageRectF.Width,souce_imageRectF.Height,UnitPixel);}void CHandleImage::DrawRectImageOnImageOne(CRect &rect)//在m_image上画图片  屏幕中显示的是实时矩形的大小{int distanceToyuandian_x;int distanceToyuandian_y;double radio_distance_x;double radio_distance_y;double radio_width;double radio_height;distanceToyuandian_x=rect.TopLeft().x-10-m_RectTracker1.m_rect.TopLeft().x;distanceToyuandian_y=rect.TopLeft().y-10-m_RectTracker1.m_rect.TopLeft().y;radio_distance_x=(double)distanceToyuandian_x/(double)m_RectTracker1.m_rect.Width();radio_distance_y=(double)distanceToyuandian_y/(double)m_RectTracker1.m_rect.Height();radio_width=(double)(rect.Width()+20)/(double)m_RectTracker1.m_rect.Width();radio_height=(double)(rect.Height()+20)/(double)m_RectTracker1.m_rect.Height();RectF souce_imageRectF;souce_imageRectF.X=radio_distance_x*m_pImageObj->GetWidth();souce_imageRectF.Y=radio_distance_y*m_pImageObj->GetHeight();souce_imageRectF.Width=radio_width*m_pImageObj->GetWidth();souce_imageRectF.Height=radio_height*m_pImageObj->GetHeight();RectF rect2Des;rect2Des.X=rect.TopLeft().x-10;rect2Des.Y=rect.TopLeft().y-10;rect2Des.Width=rect.Width()+20;rect2Des.Height=rect.Height()+20;m_pGraphics1->DrawImage(m_pImageObj,rect2Des,souce_imageRectF.X,souce_imageRectF.Y,souce_imageRectF.Width,souce_imageRectF.Height,UnitPixel);}void CHandleImage::DrawRectImageOnUnit(CRect &rect) //  分块处理时,根据实时矩形rect 在原图上进行重绘  目的是为了减少闪烁{double topLeft_x;double topLeft_y;//  首先计算分块单元上的矩形   当映射到 整篇处理时的对应位置,然后根据DrawRectImageOnImageOne中的函数 重新映射到分块上画图topLeft_x=(rect.TopLeft().x-5-m_unitTracker.m_rect.TopLeft().x)/(double)m_unitTracker.m_rect.Width()*headRectTraker->rectLock.m_rect.Width()+headRectTraker->rectLock.m_rect.TopLeft().x; //  分块区域上 矩形左上角 相对于m_RectTracker1 的坐标系下坐标topLeft_y=(rect.TopLeft().y-5-m_unitTracker.m_rect.TopLeft().y)/(double)m_unitTracker.m_rect.Height()*headRectTraker->rectLock.m_rect.Height()+headRectTraker->rectLock.m_rect.TopLeft().y; //  double width=(double)(rect.Width()+10)/m_unitTracker.m_rect.Width()*headRectTraker->rectLock.m_rect.Width();  // 相对于父块m_RectTracker1的宽度double height=(double)(rect.Height()+10)/m_unitTracker.m_rect.Height()*headRectTraker->rectLock.m_rect.Height();CRect rect_Whole(topLeft_x,topLeft_y,topLeft_x+width,topLeft_y+height); //映射到整篇处理时,对应的矩形double distanceToyuandian_x;double distanceToyuandian_y;double radio_distance_x;double radio_distance_y;double radio_width;double radio_height;distanceToyuandian_x=topLeft_x-m_RectTracker1.m_rect.TopLeft().x;distanceToyuandian_y=topLeft_y-m_RectTracker1.m_rect.TopLeft().y;radio_distance_x=(double)distanceToyuandian_x/(double)m_RectTracker1.m_rect.Width();radio_distance_y=(double)distanceToyuandian_y/(double)m_RectTracker1.m_rect.Height();radio_width=(double)(width)/(double)m_RectTracker1.m_rect.Width();radio_height=(double)(height)/(double)m_RectTracker1.m_rect.Height();RectF souce_imageRectF;souce_imageRectF.X=radio_distance_x*m_pImageObj->GetWidth();souce_imageRectF.Y=radio_distance_y*m_pImageObj->GetHeight();souce_imageRectF.Width=radio_width*m_pImageObj->GetWidth();souce_imageRectF.Height=radio_height*m_pImageObj->GetHeight();RectF rect2Des;rect2Des.X=rect.TopLeft().x-5;rect2Des.Y=rect.TopLeft().y-5;rect2Des.Width=rect.Width()+10;rect2Des.Height=rect.Height()+10;m_pGraphics1->DrawImage(m_pImageObj,rect2Des,souce_imageRectF.X,souce_imageRectF.Y,souce_imageRectF.Width,souce_imageRectF.Height,UnitPixel);}void CHandleImage::DrawRectLock()  // 画所有的矩形区域{if (headRectTraker!=NULL){CRectTracker_Lock *p=headRectTraker;while(p!=NULL){DrawTheRect(p);if (p==headRectTraker)   // 最新选择的区域保存在头结点中 DrawRectImage(p);p=p->next;}}if(headRectTraker!=NULL)DrawLine(m_p1,m_p2,m_offPt);}void CHandleImage::DrawRectLock(CPoint pt)  // 画所有的矩形区域{if (headRectTraker!=NULL){BOOL bFirstLook=m_bLook;CRectTracker_Lock *p=headRectTraker;while(p!=NULL){if (bFirstLook) //查看链表中 设置bSelected标志的第一个元素{if (p->bSelected){DrawTheRect(p,pt,TRUE);DrawRectImage(p);bFirstLook=FALSE;}elseDrawTheRect(p,pt,FALSE);}else{if (p==headRectTraker)   // 最新选择的区域保存在头结点中 DrawRectImage(p);DrawTheRect(p,pt,FALSE);}p=p->next;}if(headRectTraker!=NULL)DrawLine(m_p1,m_p2,pt);}}//--------void CHandleImage::DrawRectLockInFenKuai(CPoint pt,CRect sourceRc,BOOL bFenKuai)  // 画分块的所有矩形   sourceRc为分块在原图中的位置  bFenKuai  是否录入分块{if (headRectTraker!=NULL){BOOL bFirstLook=m_bLook;CRectTracker_Lock *p=headRectTraker;while(p!=NULL){if (bFenKuai){if (RectInFenKuai(p,sourceRc)){if (bFirstLook) //查看链表中 设置bSelected标志的第一个元素{if (p->bSelected){DrawTheRect(p,pt,TRUE);DrawRectImage(p);bFirstLook=FALSE;}elseDrawTheRect(p,pt,FALSE);}else{if (p==headRectTraker)   // 最新选择的区域保存在头结点中 DrawRectImage(p);DrawTheRect(p,pt,FALSE);}}if(headRectTraker!=NULL)DrawLine(m_p1,m_p2,m_offPt);p=p->next;}else{if (bFirstLook) //查看链表中 设置bSelected标志的第一个元素{if (p->bSelected){DrawTheRect(p,pt,TRUE);DrawRectImage(p);bFirstLook=FALSE;}elseDrawTheRect(p,pt,FALSE);}else{if (p==headRectTraker)   // 最新选择的区域保存在头结点中 DrawRectImage(p);DrawTheRect(p,pt,FALSE);}p=p->next;if(headRectTraker!=NULL)DrawLine(m_p1,m_p2,m_offPt);}}}}BOOL CHandleImage::RectInFenKuai(CRectTracker_Lock *p,CRect sourceRc){if (p==NULL)   return FALSE;else{sourceRc.top-=10;sourceRc.left-=10;sourceRc.right+=10;sourceRc.bottom+=10;RectF rectF;CRect tempRc;   this->GetRectImage(p,rectF);   tempRc.top=rectF.Y;    tempRc.left=rectF.X;   tempRc.right=rectF.X+rectF.Width;   tempRc.bottom=rectF.Y+rectF.Height;   if (sourceRc.PtInRect(tempRc.TopLeft())||sourceRc.PtInRect(tempRc.BottomRight()))      return TRUE;   else   return FALSE;}}//--------void CHandleImage::DrawTheRect(CRectTracker_Lock* q)  //画单个矩形{int org_x=m_RectTracker1.m_rect.TopLeft().x+q->radio_distance_x*m_RectTracker1.m_rect.Width();int org_y=m_RectTracker1.m_rect.TopLeft().y+q->radio_distance_y*m_RectTracker1.m_rect.Height();int width=q->radio_width*m_RectTracker1.m_rect.Width();int height=q->radio_height*m_RectTracker1.m_rect.Height();SolidBrush brushF(Color(100,0,255,0));SolidBrush brush(Color(100,255,0,0));if (q==headRectTraker)m_pGraphics1->FillRectangle( &brushF/*new SolidBrush(Color(100,0,255,0))*/,org_x,org_y,width,height);elsem_pGraphics1->FillRectangle( &brush/*new SolidBrush(Color(100,255,0,0))*/,org_x,org_y,width,height);//m_pGraphics1->DrawRectangle(new Pen(Color(255,0,0,255),5),org_x,org_y,width,height);}void CHandleImage::DrawTheRect(CRectTracker_Lock* q,CPoint pt){int org_x=m_RectTracker1.m_rect.TopLeft().x+q->radio_distance_x*m_RectTracker1.m_rect.Width();int org_y=m_RectTracker1.m_rect.TopLeft().y+q->radio_distance_y*m_RectTracker1.m_rect.Height();int width=q->radio_width*m_RectTracker1.m_rect.Width();int height=q->radio_height*m_RectTracker1.m_rect.Height();SolidBrush brushF(Color(100,0,255,0));SolidBrush brush(Color(100,255,0,0));if (q==headRectTraker)m_pGraphics1->FillRectangle( &brushF /*new SolidBrush(Color(100,0,255,0))*/,org_x-pt.x,org_y-pt.y,width,height);elsem_pGraphics1->FillRectangle( &brush /*new SolidBrush(Color(100,255,0,0))*/,org_x-pt.x,org_y-pt.y,width,height);//m_pGraphics1->FillRectangle(new SolidBrush(Color(100,255,0,0)),org_x-pt.x,org_y-pt.y,width,height);}void CHandleImage::DrawTheRect(CRectTracker_Lock* q,CPoint pt,BOOL bFirst){int org_x=m_RectTracker1.m_rect.TopLeft().x+q->radio_distance_x*m_RectTracker1.m_rect.Width();int org_y=m_RectTracker1.m_rect.TopLeft().y+q->radio_distance_y*m_RectTracker1.m_rect.Height();int width=q->radio_width*m_RectTracker1.m_rect.Width();int height=q->radio_height*m_RectTracker1.m_rect.Height();SolidBrush brush(Color(100,255,0,0));SolidBrush brushH(Color(100,0,255,0));SolidBrush brushF(Color(100,0,0,255));if (m_bLook){if (bFirst)m_pGraphics1->FillRectangle( &brushF /*new SolidBrush(Color(100,0,255,0))*/,org_x-pt.x,org_y-pt.y,width,height);elsem_pGraphics1->FillRectangle( &brush /*new SolidBrush(Color(100,255,0,0))*/,org_x-pt.x,org_y-pt.y,width,height);}else{if (q==headRectTraker)m_pGraphics1->FillRectangle( &brushH /*new SolidBrush(Color(100,0,255,0))*/,org_x-pt.x,org_y-pt.y,width,height);elsem_pGraphics1->FillRectangle( &brush /*new SolidBrush(Color(100,255,0,0))*/,org_x-pt.x,org_y-pt.y,width,height);}}void CHandleImage::DrawTheRectOnUnit(CRectTracker_Lock* q){int org_x=m_unitTracker.m_rect.TopLeft().x+q->radio_distance_x*m_unitTracker.m_rect.Width();int org_y=m_unitTracker.m_rect.TopLeft().y+q->radio_distance_y*m_unitTracker.m_rect.Height();int width=q->radio_width*m_unitTracker.m_rect.Width();int height=q->radio_height*m_unitTracker.m_rect.Height();m_pGraphics1->FillRectangle(new SolidBrush(Color(100,255,0,0)),org_x,org_y,width,height);}void CHandleImage::DrawUnitImageOnImageOne(CRect &rect){int distanceToyuandian_x;int distanceToyuandian_y;double radio_distance_x;double radio_distance_y;double radio_width;double radio_height;distanceToyuandian_x=rect.TopLeft().x-m_RectTracker1.m_rect.TopLeft().x;distanceToyuandian_y=rect.TopLeft().y-m_RectTracker1.m_rect.TopLeft().y;radio_distance_x=(double)distanceToyuandian_x/(double)m_RectTracker1.m_rect.Width();radio_distance_y=(double)distanceToyuandian_y/(double)m_RectTracker1.m_rect.Height();radio_width=(double)(rect.Width())/(double)m_RectTracker1.m_rect.Width();radio_height=(double)(rect.Height())/(double)m_RectTracker1.m_rect.Height();RectF souce_imageRectF;souce_imageRectF.X=radio_distance_x*m_pImageObj->GetWidth();souce_imageRectF.Y=radio_distance_y*m_pImageObj->GetHeight();souce_imageRectF.Width=radio_width*m_pImageObj->GetWidth();souce_imageRectF.Height=radio_height*m_pImageObj->GetHeight();CRect unitRect=m_unitTracker.m_rect;RectF rect2Des;rect2Des.X=unitRect.TopLeft().x;rect2Des.Y=unitRect.TopLeft().y;rect2Des.Width=unitRect.Width();rect2Des.Height=unitRect.Height();m_pGraphics1->DrawImage(m_pImageObj,rect2Des,souce_imageRectF.X,souce_imageRectF.Y,souce_imageRectF.Width,souce_imageRectF.Height,UnitPixel);if (headRectTrakerOnUnit!=NULL){CRectTracker_Lock *p=headRectTrakerOnUnit;while(p!=NULL){DrawTheRectOnUnit(p);if (p==headRectTrakerOnUnit)   // 最新选择的区域保存在头结点中  DrawRectImageFromUnitOnImageOne(p->rectLock.m_rect);p=p->next;}if(m_bFixedColumn){DrawLine(m_p1,m_p2,m_offPt);}}}void CHandleImage::GetTheRadio(CRectTracker_Lock *q){CRect rect=q->rectLock.m_rect;int distanceToyuandian_x;int distanceToyuandian_y;double radio_distance_x;double radio_distance_y;double radio_width;double radio_height;distanceToyuandian_x=q->rectLock.m_rect.TopLeft().x-m_RectTracker1.m_rect.TopLeft().x;distanceToyuandian_y=q->rectLock.m_rect.TopLeft().y-m_RectTracker1.m_rect.TopLeft().y;int W=m_RectTracker1.m_rect.Width();int Y=m_RectTracker1.m_rect.Height();radio_distance_x=(double)distanceToyuandian_x/(double)m_RectTracker1.m_rect.Width();radio_distance_y=(double)distanceToyuandian_y/(double)m_RectTracker1.m_rect.Height();radio_width=(double)rect.Width()/(double)m_RectTracker1.m_rect.Width();radio_height=(double)rect.Height()/(double)m_RectTracker1.m_rect.Height();if(q!=NULL){q->radio_distance_x=radio_distance_x;q->radio_distance_y=radio_distance_y;q->radio_width=radio_width;q->radio_height=radio_height;}}void CHandleImage::GetTheRadioOnUnit(CRectTracker_Lock *q){CRect rect=q->rectLock.m_rect;int distanceToyuandian_x;int distanceToyuandian_y;double radio_distance_x;double radio_distance_y;double radio_width;double radio_height;distanceToyuandian_x=rect.TopLeft().x-m_unitTracker.m_rect.TopLeft().x;distanceToyuandian_y=rect.TopLeft().y-m_unitTracker.m_rect.TopLeft().y;radio_distance_x=(double)distanceToyuandian_x/(double)m_unitTracker.m_rect.Width();radio_distance_y=(double)distanceToyuandian_y/(double)m_unitTracker.m_rect.Height();radio_width=(double)(rect.Width())/(double)m_unitTracker.m_rect.Width();radio_height=(double)(rect.Height())/(double)m_unitTracker.m_rect.Height();q->radio_distance_x=radio_distance_x;q->radio_distance_y=radio_distance_y;q->radio_height=radio_height;q->radio_width=radio_width;}void CHandleImage::GetRectImage(CRectTracker_Lock *q, RectF &rect){if (m_pImageObj!=NULL&&q!=NULL){int org_x=q->radio_distance_x*m_pImageObj->GetWidth();  //RECT区域中的图片起始点int org_y=q->radio_distance_y*m_pImageObj->GetHeight();int width=q->radio_width*m_pImageObj->GetWidth();      //RECT区域在图像中的宽高int height=q->radio_height*m_pImageObj->GetHeight();rect.X=org_x;rect.Y=org_y;rect.Width=width;rect.Height=height;}}void CHandleImage::GetUnitRectImageInfo(CRectTracker_Lock *q, RectF &souce_imageRectF){double topLeftUnit_x=m_unitTracker.m_rect.TopLeft().x+q->radio_distance_x*m_unitTracker.m_rect.Width();double topLeftUnit_y=m_unitTracker.m_rect.TopLeft().y+q->radio_distance_y*m_unitTracker.m_rect.Height();double bottomRightUnit_x=topLeftUnit_x+q->radio_width*m_unitTracker.m_rect.Width();double bottomRightUnit_y=topLeftUnit_y+q->radio_height*m_unitTracker.m_rect.Height();   // 矩形在分块处理时的坐标double topLeftWhole_x;double topLeftWhole_y;//  首先计算分块单元上的矩形   当映射到 整篇处理时的对应位置,然后根据DrawRectImageOnImageOne中的函数 重新映射到分块上画图topLeftWhole_x=(topLeftUnit_x-m_unitTracker.m_rect.TopLeft().x)/(double)m_unitTracker.m_rect.Width()*headRectTraker->rectLock.m_rect.Width()+headRectTraker->rectLock.m_rect.TopLeft().x; //  分块区域上 矩形左上角 相对于m_RectTracker1 的坐标系下坐标topLeftWhole_y=(topLeftUnit_y-m_unitTracker.m_rect.TopLeft().y)/(double)m_unitTracker.m_rect.Height()*headRectTraker->rectLock.m_rect.Height()+headRectTraker->rectLock.m_rect.TopLeft().y; //  double widthWhole=(double)(bottomRightUnit_x-topLeftUnit_x)/m_unitTracker.m_rect.Width()*headRectTraker->rectLock.m_rect.Width();  // 相对于父块m_RectTracker1的宽度double heightWhole=(double)(bottomRightUnit_y-topLeftUnit_y)/m_unitTracker.m_rect.Height()*headRectTraker->rectLock.m_rect.Height();double distanceToyuandian_x;double distanceToyuandian_y;double radio_distance_x;double radio_distance_y;double radio_width;double radio_height;distanceToyuandian_x=topLeftWhole_x-m_RectTracker1.m_rect.TopLeft().x;distanceToyuandian_y=topLeftWhole_y-m_RectTracker1.m_rect.TopLeft().y;radio_distance_x=(double)distanceToyuandian_x/(double)m_RectTracker1.m_rect.Width();radio_distance_y=(double)distanceToyuandian_y/(double)m_RectTracker1.m_rect.Height();radio_width=(double)(widthWhole)/(double)m_RectTracker1.m_rect.Width();radio_height=(double)(heightWhole)/(double)m_RectTracker1.m_rect.Height();souce_imageRectF.X=radio_distance_x*m_pImageObj->GetWidth();souce_imageRectF.Y=radio_distance_y*m_pImageObj->GetHeight();souce_imageRectF.Width=radio_width*m_pImageObj->GetWidth();souce_imageRectF.Height=radio_height*m_pImageObj->GetHeight();}void CHandleImage::NewNode(){CRectTracker_Lock *pUnit=headRectTrakerOnUnit,*qUnit=NULL;while(pUnit!=NULL){qUnit=pUnit;pUnit=pUnit->next;delete qUnit;}headRectTrakerOnUnit=NULL;CRect  rect(m_leftBnDown.x,m_leftBnDown.y,m_movePoint.x,m_movePoint.y);CRectTracker rectTracker(&rect,CRectTracker::dottedLine);CRectTracker_Lock *q=new CRectTracker_Lock;m_p1.X=rect.TopLeft().x-rect.Width();  //  以新建的矩形为起始矩形定位 Line的坐标m_p1.Y=rect.TopLeft().y;m_p2.X=m_p1.X;m_p2.Y=rect.BottomRight().y;m_step=0;if (headRectTraker==NULL){q->rectLock=rectTracker;q->next=NULL;headRectTraker=q;}else{if(headRectTraker->rectLock.m_rect.IsRectEmpty())     // 删除是空矩形的头结点{delete headRectTraker;headRectTraker=NULL;q->rectLock=rectTracker;q->next=NULL;headRectTraker=q;}else{q->rectLock=rectTracker;q->next=headRectTraker;headRectTraker=q;    //将新节点作为头节点}}GetTheRadio(q);//在m_image2上设置橡皮筋区域}void CHandleImage::NewNode(double radio_distance_x,double radio_distance_y,double radio_width,double radio_height)  // 新节点作为头结点{CRectTracker_Lock *pUnit=headRectTrakerOnUnit,*qUnit=NULL;while(pUnit!=NULL){qUnit=pUnit;pUnit=pUnit->next;delete qUnit;}headRectTrakerOnUnit=NULL;CRectTracker_Lock *q=new CRectTracker_Lock;q->radio_distance_x=radio_distance_x;q->radio_distance_y=radio_distance_y;q->radio_width=radio_width;q->radio_height=radio_height;m_step=0;if (headRectTraker==NULL){q->next=NULL;headRectTraker=q;}else{/*if(headRectTraker->rectLock.m_rect.IsRectEmpty())     // 删除是空矩形的头结点{delete headRectTraker;headRectTraker=NULL;q->next=NULL;headRectTraker=q;}else{*/    q->next=headRectTraker;headRectTraker=q;    //将新节点作为头节点//}}}void CHandleImage::NewNodeTail(double radio_distance_x,double radio_distance_y,double radio_width,double radio_height){CRectTracker_Lock *pUnit=headRectTrakerOnUnit,*qUnit=NULL;while(pUnit!=NULL){qUnit=pUnit;pUnit=pUnit->next;delete qUnit;}headRectTrakerOnUnit=NULL;CRectTracker_Lock *q=new CRectTracker_Lock;q->radio_distance_x=radio_distance_x;q->radio_distance_y=radio_distance_y;q->radio_width=radio_width;q->radio_height=radio_height;m_step=0;if (headRectTraker==NULL){q->next=NULL;headRectTraker=q;}else{CRectTracker_Lock *p=headRectTraker;while(p->next!=NULL)p=p->next;p->next=q;q->next=NULL;    //新加结点作为尾结点}}void CHandleImage::AdjustNode(CRect & rc,CRectTracker_Lock *p){CRect rect;rect.left=rc.left+p->radio_distance_x*rc.Width();rect.right=rect.left+p->radio_width*rc.Width();rect.top=rc.top+p->radio_distance_y*rc.Height();rect.bottom=rect.top+p->radio_height*rc.Height();CRectTracker rectTracker(&rect,CRectTracker::dottedLine);p->rectLock=rectTracker;m_p1.X=rect.TopLeft().x-rect.Width();  //  以新建的矩形为起始矩形定位 Line的坐标m_p1.Y=rect.TopLeft().y;m_p2.X=m_p1.X;m_p2.Y=rect.BottomRight().y;}void CHandleImage::AdjuctAllNodes(CRect & rc){CRectTracker_Lock *p=headRectTraker;while(p!=NULL){AdjustNode(rc,p);p=p->next;}}void CHandleImage::Erase(CPoint point){CRectTracker_Lock* p=headRectTraker,*pre=NULL;if (p==NULL||p->rectLock.m_rect.IsRectEmpty()){MessageBox(NULL,_T("所有区域均以被察除,请重新设置"),_T("察除信息"),MB_OK);}else{while (p!=NULL){//AdjustRect(p); // 调整矩形大小   否则移动图片后会出现问题if (p->rectLock.HitTest(point)>=0){if (p==headRectTraker){headRectTraker=p->next;delete p;p=headRectTraker;pre=NULL;//if(p!=NULL)//m_RectTracker2.m_rect.SetRect(0,0,p->rectLock.m_rect.Width(),p->rectLock.m_rect.Height());   //删除节点后,要将橡皮筋的区域重新设置,使其为新链条头节点的区域}else{pre->next=p->next;delete p;p=pre->next;//if(p!=NULL)//m_RectTracker2.m_rect.SetRect(0,0,p->rectLock.m_rect.Width(),p->rectLock.m_rect.Height());   //删除节点后,要将橡皮筋的区域重新设置,使其为新链条头节点的区域}}else{// 未在P的区域if (p==headRectTraker){pre=headRectTraker;p=p->next;}else{p=p->next;  pre=pre->next;}}}}if (headRectTraker!=NULL){m_p1.X=headRectTraker->rectLock.m_rect.TopLeft().x-headRectTraker->rectLock.m_rect.Width();m_p1.Y=headRectTraker->rectLock.m_rect.TopLeft().y;m_p2.X=m_p1.X;m_p2.Y=headRectTraker->rectLock.m_rect.BottomRight().y;}}void CHandleImage::EraseAll(){CRectTracker_Lock *p=headRectTraker;while(p!=NULL){headRectTraker=p->next;delete p;p=headRectTraker;}headRectTraker=NULL;}

void CHandleImage::EraseNodesInRect(CRect rect){

 CRectTracker_Lock* p=headRectTraker,*pre=NULL; if (p==NULL||p->rectLock.m_rect.IsRectEmpty()) {  MessageBox(NULL,_T("所有区域均以被察除,请重新设置"),_T("察除信息"),MB_OK); }else{  RectF sourceRcF;  CRect rc;  while (p!=NULL)  {   GetRectImage(p,sourceRcF);

   rc.left=sourceRcF.GetLeft();   rc.top=sourceRcF.GetTop();   rc.right=sourceRcF.GetRight();   rc.bottom=sourceRcF.GetBottom();

      if (rect.PtInRect(rc.TopLeft())||rect.PtInRect(rc.BottomRight()))   {    if (p==headRectTraker)    {     headRectTraker=p->next;     delete p;     p=headRectTraker;     pre=NULL;    }else{     pre->next=p->next;     delete p;     p=pre->next;    }   }else{// 未在P的区域

    if (p==headRectTraker)    {     pre=headRectTraker;     p=p->next;    }else{     p=p->next;       pre=pre->next;    }   }  } }

 if (headRectTraker!=NULL) {  m_p1.X=headRectTraker->rectLock.m_rect.TopLeft().x-headRectTraker->rectLock.m_rect.Width();  m_p1.Y=headRectTraker->rectLock.m_rect.TopLeft().y;  m_p2.X=m_p1.X;  m_p2.Y=headRectTraker->rectLock.m_rect.BottomRight().y; }}

void CHandleImage::Look(CPoint point){CRectTracker_Lock* p=headRectTraker,*pre=NULL;CRectTracker_Lock* pFirst=NULL; // 记录点击之前第一个bSeleted位置,否则 若是点击在所有区域之外,则所有区域的bSelected均为False了if (p==NULL||p->rectLock.m_rect.IsRectEmpty()){MessageBox(NULL,_T("无可供查看的区域"),_T("查看区域"),MB_OK);}else{BOOL bHit=FALSE;// 是否击中区域while (p!=NULL){//AdjustRect(p); // 调整矩形大小 否则移动图片后会出现问题if (p->rectLock.HitTest(point)>=0){bHit=TRUE;if (p==headRectTraker){p->bSelected=TRUE;break;/*headRectTraker=p->next;delete p;p=headRectTraker;pre=NULL;*///if(p!=NULL)//m_RectTracker2.m_rect.SetRect(0,0,p->rectLock.m_rect.Width(),p->rectLock.m_rect.Height()); //删除节点后,要将橡皮筋的区域重新设置,使其为新链条头节点的区域}else{p->bSelected=TRUE;break;/*pre->next=p->next;delete p;p=pre->next;*///if(p!=NULL)//m_RectTracker2.m_rect.SetRect(0,0,p->rectLock.m_rect.Width(),p->rectLock.m_rect.Height()); //删除节点后,要将橡皮筋的区域重新设置,使其为新链条头节点的区域}}else{// 未在P的区域if (p==headRectTraker){if(p->bSelected)pFirst=p;p->bSelected=FALSE;pre=headRectTraker;p=p->next;}else{if(pFirst==NULL)if(p->bSelected)pFirst=p;p->bSelected=FALSE;p=p->next; pre=pre->next;}}}if(!bHit){if(pFirst!=NULL)pFirst->bSelected=TRUE;elseif(headRectTraker!=NULL)headRectTraker->bSelected=TRUE;}}/*if (headRectTraker!=NULL){m_p1.X=headRectTraker->rectLock.m_rect.TopLeft().x-headRectTraker->rectLock.m_rect.Width();m_p1.Y=headRectTraker->rectLock.m_rect.TopLeft().y;m_p2.X=m_p1.X;m_p2.Y=headRectTraker->rectLock.m_rect.BottomRight().y;}*/}/*CR_LOCK* CHandleImage::FindFirstToLook(){ CRectTracker_Lock * p=headRectTraker;while(p!=NULL){if (p->bSelected)return p;p=p->next;}return NULL;}*/void CHandleImage::LineMoveLeft(unsigned int i){m_step=m_step+i;CRect rect;CRect shuanxinRect;RectF sourceRectF;RectF desRectF;if (headRectTraker!=NULL){rect=headRectTraker->rectLock.m_rect;CRect rectTemp;AdjustRect(headRectTraker);rectTemp=headRectTraker->rectLock.m_rect;if(m_step==i||rect!=rectTemp){ // rect!=rectTemp 暗示曾移动过m_p1.X=rectTemp.TopLeft().x-rectTemp.Width();m_p1.Y=rectTemp.TopLeft().y;m_p2.X=rectTemp.TopLeft().x-rectTemp.Width();m_p2.Y=rectTemp.BottomRight().y;}rect=rectTemp;m_p1.X=m_p1.X-i;m_p2.X=m_p2.X-i;shuanxinRect.TopLeft().x=m_p1.X;shuanxinRect.TopLeft().y=m_p1.Y;if(m_p1.X+5<rect.TopLeft().x)shuanxinRect.BottomRight().x=m_p1.X+5;elseshuanxinRect.BottomRight().x=rect.TopLeft().x;shuanxinRect.BottomRight().y=rect.BottomRight().y;CRectTracker_Lock * p=new CRectTracker_Lock;p->next=NULL;p->rectLock.m_rect=shuanxinRect;GetTheRadio(p);GetRectImage(p,sourceRectF);desRectF.X=shuanxinRect.TopLeft().x;desRectF.Y=shuanxinRect.TopLeft().y;desRectF.Width=shuanxinRect.Width();desRectF.Height=shuanxinRect.Height();m_pGraphics1->DrawImage(m_pImageObj,desRectF,sourceRectF.X,sourceRectF.Y,sourceRectF.Width,sourceRectF.Height,UnitPixel);delete p;//DrawLine(m_p1,m_p2,m_offPt);DrawLine(m_p1,m_p2);}}void CHandleImage::LineMoveRight(unsigned int i){m_step=m_step-i;CRect rect;CRect shuanxinRect;RectF sourceRectF;RectF desRectF;if (headRectTraker!=NULL){rect=headRectTraker->rectLock.m_rect;CRect rectTemp;AdjustRect(headRectTraker);rectTemp=headRectTraker->rectLock.m_rect;if(m_step==-i||rect!=rectTemp){ // rect!=rectTemp 暗示曾移动过m_p1.X=rectTemp.TopLeft().x-rectTemp.Width();m_p1.Y=rectTemp.TopLeft().y;m_p2.X=rectTemp.TopLeft().x-rectTemp.Width();m_p2.Y=rectTemp.BottomRight().y;}rect=rectTemp;m_p1.X=m_p1.X+i;m_p2.X=m_p2.X+i;shuanxinRect.TopLeft().x=m_p1.X-5;shuanxinRect.TopLeft().y=m_p1.Y;shuanxinRect.BottomRight().x=m_p2.X;shuanxinRect.BottomRight().y=m_p2.Y;CRectTracker_Lock * p=new CRectTracker_Lock;p->next=NULL;p->rectLock.m_rect=shuanxinRect;GetTheRadio(p);GetRectImage(p,sourceRectF);desRectF.X=shuanxinRect.TopLeft().x;desRectF.Y=shuanxinRect.TopLeft().y;desRectF.Width=shuanxinRect.Width();desRectF.Height=shuanxinRect.Height();m_pGraphics1->DrawImage(m_pImageObj,desRectF,sourceRectF.X,sourceRectF.Y,sourceRectF.Width,sourceRectF.Height,UnitPixel);delete p;//DrawLine(m_p1,m_p2,m_offPt);DrawLine(m_p1,m_p2);}}void CHandleImage::KeyDownToCreateOneNode(){CRect rectBeforeMove;CRect rectAfterMove;rectBeforeMove=headRectTraker->rectLock.m_rect;AdjustRect(headRectTraker);rectAfterMove=headRectTraker->rectLock.m_rect;if(rectBeforeMove!=rectAfterMove) //说明橡皮筋移动过 所以要重新设定竖线的起始位置{m_p1.X=rectAfterMove.TopLeft().x-rectAfterMove.Width();m_p1.Y=rectAfterMove.TopLeft().y;m_p2.X=m_p1.X;m_p2.Y=rectAfterMove.BottomRight().y;DrawLine(m_p1,m_p2);//return;}m_step=0;CRect rect(m_p1.X,m_p1.Y,headRectTraker->rectLock.m_rect.TopLeft().x,headRectTraker->rectLock.m_rect.BottomRight().y);CRectTracker rectTracker(&rect,CRectTracker::dottedLine);CRectTracker_Lock *q=new CRectTracker_Lock;q->rectLock=rectTracker;q->next=headRectTraker;headRectTraker=q;GetTheRadio(q);//在m_image2上设置橡皮筋区域RectF souce_imageRectF;GetRectImage(q,souce_imageRectF);/*CRect rectTracker2=m_RectTracker2.m_rect;CRect clientImage2Rect;m_pGraphics2.GetClientRect(&clientImage2Rect);if (rectTracker2.TopLeft().x<0) rectTracker2.TopLeft().x=0;if (rectTracker2.TopLeft().y<0) rectTracker2.TopLeft().y=0;if (rectTracker2.TopLeft().x>=clientImage2Rect.BottomRight().x) rectTracker2.TopLeft().x=0;if (rectTracker2.TopLeft().y>=clientImage2Rect.BottomRight().y) rectTracker2.TopLeft().y=0; m_RectTracker2.m_rect.SetRect(rectTracker2.TopLeft().x,rectTracker2.TopLeft().y,rectTracker2.TopLeft().x+souce_imageRectF.Width,rectTracker2.TopLeft().y+souce_imageRectF.Height);m_image2.GetClientRect(&rect);m_image2.ClientToScreen(&rect);this->ScreenToClient(&rect);RedrawWindow(rect);// m_image上其它位置都不变,但是新增加的区域会覆盖上去*/m_p1.X=headRectTraker->rectLock.m_rect.TopLeft().x-headRectTraker->rectLock.m_rect.Width(); //改变点的位置m_p2.X=m_p1.X;m_p1.Y=headRectTraker->rectLock.m_rect.TopLeft().y;m_p2.Y=headRectTraker->rectLock.m_rect.BottomRight().y;/*if (m_p1.X<5){CRect rect=m_RectTracker1.m_rect;CRect clientRect;m_image.GetClientRect(&clientRect);int offset=clientRect.Width()/3;m_RectTracker1.m_rect.SetRect(rect.TopLeft().x+offset,rect.TopLeft().y,rect.BottomRight().x+offset,rect.BottomRight().y);m_image.ClientToScreen(&clientRect);this->ScreenToClient(&clientRect);RedrawWindow(clientRect);AdjustRect(headRectTraker);m_p1.X=headRectTraker->rectLock.m_rect.TopLeft().x-headRectTraker->rectLock.m_rect.Width(); //改变点的位置m_p2.X=m_p1.X;m_p1.Y=headRectTraker->rectLock.m_rect.TopLeft().y;m_p2.Y=headRectTraker->rectLock.m_rect.BottomRight().y;}*/DrawLine(m_p1,m_p2);}void CHandleImage::ReSetLinePos(){if (headRectTraker!=NULL){AdjustRect(headRectTraker);m_p1.X=headRectTraker->rectLock.m_rect.TopLeft().x-headRectTraker->rectLock.m_rect.Width();m_p1.Y=headRectTraker->rectLock.m_rect.TopLeft().y;m_p2.X=m_p1.X;m_p2.Y=headRectTraker->rectLock.m_rect.BottomRight().y;}}CPoint CHandleImage::AdjustTracker(CRect clientRect){CPoint pt;pt.x=pt.y=0;if (m_p1.X<5){CRect rect=m_RectTracker1.m_rect;int offset=clientRect.Width()/3;pt.x=offset;m_RectTracker1.m_rect.SetRect(rect.TopLeft().x+offset,rect.TopLeft().y,rect.BottomRight().x+offset,rect.BottomRight().y);if (headRectTraker!=NULL){AdjustRect(headRectTraker);m_p1.X=headRectTraker->rectLock.m_rect.TopLeft().x-headRectTraker->rectLock.m_rect.Width(); //改变点的位置m_p2.X=m_p1.X;m_p1.Y=headRectTraker->rectLock.m_rect.TopLeft().y;m_p2.Y=headRectTraker->rectLock.m_rect.BottomRight().y;}}return pt;}


 

 

使用时要先初始化,主要初始化m_pImageObj、m_pGraphics1、rectTracker1

 

初始化阶段:

      1.   设置要处理的图像 

     m_handleImage.m_pImageObj=m_pImage; //m_pImageObj为Bitmap*类型  可以在OnDraw中设置

 

     2.  设置处理图像的绘图设备环境
     

    需在OnDraw中设置if (m_handleImage.headRectTraker!=NULL){if (m_handleImage.m_pGraphics1!=NULL)delete m_handleImage.m_pGraphics1;Graphics *pG=new Graphics(&bmp);m_handleImage.m_pGraphics1=pG;    //所有的绘制工作都是在位图中预先绘制pt=m_ClientRect.TopLeft();  //新建位图Bitmap bmp(m_ClientRect.Width(),m_ClientRect.Height());相对于视图的偏移量m_handleImage.DrawRectLock(pt); //位图绘制完毕后,将绘图设备重置为:视图绘图区 GetDC()->m_hDCif (m_handleImage.m_pGraphics1!=NULL)delete m_handleImage.m_pGraphics1;m_handleImage.m_pGraphics1=new Graphics(GetDC()->m_hDC);}


 

需在锁定时设置void NewImageView::OnBnClickedButton7()  //锁定图片{// TODO: 在此添加控件通知处理程序代码m_handleImage.m_bLock=!m_handleImage.m_bLock;if (m_handleImage.m_bLock){GetDlgItem(IDC_BUTTON7)->SetWindowText(_T("取消锁定"));}else{GetDlgItem(IDC_BUTTON7)->SetWindowText(_T("锁定图片"));}SetRectTracker();  Invalidate(FALSE);if(m_handleImage.m_pGraphics1!=NULL)   //  实时更新绘图设备上下文环境{delete m_handleImage.m_pGraphics1;m_handleImage.m_pGraphics1=new Graphics(GetDC()->m_hDC);}elsem_handleImage.m_pGraphics1=new Graphics(GetDC()->m_hDC);}


 


  3  以屏幕显示的图像为橡皮筋区域,设置橡CHandleImage类的皮筋区域(橡皮筋区域的坐标为视图坐标系) 
    
     在ONSIZE中 需重新设置橡皮筋区域
     在放大缩小或移动图片时,也需要重新设置橡皮筋区域

  void NewImageView::SetRectTracker()  {  CRectTracker rectTracker1;  int x,y,cx,cy; //橡皮筋的起始位置和长宽  rectTracker1.Draw(GetDC());  int nWidth = m_ImgW/m_fRate*m_fzoom;  int nHeight = m_ImgH/m_fRate*m_fzoom;  if(m_fzoom>1.0)  {  x=m_ClientRect.TopLeft().x+m_Point.x;  y=m_ClientRect.TopLeft().y+m_Point.y;  cx=m_pBmp->GetWidth();  cy=m_pBmp->GetHeight();  }  else  {  x=m_ClientRect.TopLeft().x+(m_ClientRect.Width()-nWidth)/2;  y=m_ClientRect.TopLeft().y+(m_ClientRect.Height()-nHeight)/2;  cx=m_pBmp->GetWidth();  cy=m_pBmp->GetHeight();  }  rectTracker1.m_rect.SetRect(x,y,x+cx,y+cy); //设置橡皮筋区域  m_handleImage.m_RectTracker1=rectTracker1;   m_handleImage.AdjustAllRect();  //调整矩形  m_handleImage.ReSetLinePos();   //调整线  }


 

一个简单的例子:

 

// NewImageView.cpp : 实现文件//#include "stdafx.h"#include "TreePath.h"#include "NewImageView.h"#include "MainFrm.h"#include "TreePathView.h"// NewImageViewIMPLEMENT_DYNCREATE(NewImageView, CFormView)NewImageView::NewImageView(): CFormView(NewImageView::IDD){m_pImage=NULL;m_pBmp=NULL;m_Point.x=m_Point.y=0;m_PreP=m_LbtndownP=m_Point;m_ImgW=m_ImgH=0;m_fRate=1.0;m_fzoom=1.0;m_pG=NULL;m_pGbmp=NULL;m_pMemBmp=NULL;m_pGray8pp=NULL;m_pMemCDC=NULL;m_pCBitmap=NULL;m_pTransParentBmp=NULL;//m_hAccel=NULL;}NewImageView::~NewImageView(){if (m_pImage!=NULL){delete m_pImage;}if (m_pMemBmp){delete m_pMemBmp;}if (m_pBmp){delete m_pBmp;}GdiplusShutdown(gdiplusToken);}void NewImageView::DoDataExchange(CDataExchange* pDX){CFormView::DoDataExchange(pDX);DDX_Control(pDX, IDC_BUTTON2, m_enlarge);}BEGIN_MESSAGE_MAP(NewImageView, CFormView)ON_WM_PAINT()ON_WM_SIZE()ON_BN_CLICKED(IDC_BUTTON2, &NewImageView::OnBnClickedEnLarge)ON_BN_CLICKED(IDC_BUTTON4, &NewImageView::OnBnClickedButton4)ON_BN_CLICKED(IDC_BUTTON1, &NewImageView::OnBnClickedButton1)ON_WM_ERASEBKGND()ON_BN_CLICKED(IDC_BUTTON3, &NewImageView::OnBnClickedButton3)ON_BN_CLICKED(IDC_BUTTON5, &NewImageView::OnBnClickedButton5)ON_BN_CLICKED(IDC_BUTTON6, &NewImageView::OnBnClickedButton6)ON_WM_LBUTTONDOWN()ON_WM_MOUSEMOVE()ON_WM_LBUTTONUP()//ON_COMMAND(ID_IMAGE_ENLAGGE, &NewImageView::OnImageEnlagge)ON_COMMAND(ID_Test, &NewImageView::OnTest)ON_BN_CLICKED(IDC_BUTTON7, &NewImageView::OnBnClickedButton7)END_MESSAGE_MAP()// NewImageView 诊断#ifdef _DEBUGvoid NewImageView::AssertValid() const{CFormView::AssertValid();}#ifndef _WIN32_WCEvoid NewImageView::Dump(CDumpContext& dc) const{CFormView::Dump(dc);}#endif#endif //_DEBUG// NewImageView 消息处理程序void NewImageView::OnInitialUpdate(){CFormView::OnInitialUpdate();GdiplusStartup(&gdiplusToken,&gdiplusStartupInput,NULL);//m_hAccel=::LoadAccelerators(AfxGetApp()->m_hInstance,MAKEINTRESOURCE(ID_Accelerator));//AfxGetApp()->m_hInstance//ASSERT(m_hAccel);// TODO: 在此添加专用代码和/或调用基类}void NewImageView::OnDraw(CDC* pDC){// TODO: 在此添加专用代码和/或调用基类{CRect topRect;GetClientRect(&topRect);topRect.bottom=m_ClientRect.top;pDC->FillSolidRect(topRect,RGB(0,155,155));}if (m_pImage!=NULL){m_handleImage.m_pImageObj=m_pImage;   //  ------初始化 no.1Graphics graphics(GetDC()->m_hDC);graphics.DrawImage(m_pImage,RectF(0,0,1,1),0,0,1,1,UnitPixel);int nWidth = m_ImgW/m_fRate*m_fzoom;int nHeight = m_ImgH/m_fRate*m_fzoom;Bitmap bmp(m_ClientRect.Width(),m_ClientRect.Height());Graphics grbmp(&bmp);SolidBrush blackBrush(Color(255, 255, 255));grbmp.FillRectangle(&blackBrush,0,0,m_ClientRect.Width(),m_ClientRect.Height());CPoint pt;if(m_fzoom>1.0){grbmp.DrawImage(m_pBmp,m_Point.x,m_Point.y,nWidth,nHeight);  pt=m_Point;}else{grbmp.DrawImage(m_pBmp,(m_ClientRect.Width()-nWidth)/2, (m_ClientRect.Height()-nHeight)/2, nWidth, nHeight);pt.x=(m_ClientRect.Width()-nWidth)/2;pt.y=(m_ClientRect.Height()-nHeight)/2;}if (m_handleImage.headRectTraker!=NULL){if (m_handleImage.m_pGraphics1!=NULL)delete m_handleImage.m_pGraphics1;Graphics *pG=new Graphics(&bmp);m_handleImage.m_pGraphics1=pG;pt=m_ClientRect.TopLeft();  //新建位图Bitmap bmp(m_ClientRect.Width(),m_ClientRect.Height());相对于视图的偏移量m_handleImage.DrawRectLock(pt); if (m_handleImage.m_pGraphics1!=NULL)delete m_handleImage.m_pGraphics1;m_handleImage.m_pGraphics1=new Graphics(GetDC()->m_hDC);}graphics.DrawImage(&bmp,m_ClientRect.left,m_ClientRect.top,m_ClientRect.Width(),m_ClientRect.Height());}else{pDC->FillSolidRect(m_ClientRect,RGB(255,255,255));}}void NewImageView::ReDraw(){if (m_pImage!=NULL){int nWidth = m_ImgW/m_fRate*m_fzoom;int nHeight = m_ImgH/m_fRate*m_fzoom;if(m_pBmp==NULL)  // OnSize中 delete掉m_pBmp  否则放大对话框时有问题,因为m_pBmp还是原来的尺寸,所以放大可能出现问题m_pBmp = new Bitmap(nWidth,nHeight);Graphics gbmp(m_pBmp);gbmp.Clear(Color(255,255,255,255));gbmp.DrawImage(m_pMemBmp,0,0,nWidth,nHeight);}}void NewImageView::OnSize(UINT nType, int cx, int cy){CFormView::OnSize(nType, cx, cy); if (m_enlarge.GetSafeHwnd()){CRect rect;m_enlarge.GetClientRect(&rect);GetClientRect(&m_ClientRect);m_ClientRect.top=rect.bottom;if (m_pBmp!=NULL){delete m_pBmp;m_pBmp=NULL;}if (m_pImage!=NULL){float fRateW=(float)m_ImgW/m_ClientRect.Width();float fRateH=(float)m_ImgH/m_ClientRect.Height();m_fRate=max(fRateH,fRateW);//m_handleImage.m_offPt=m_ClientRect.TopLeft();if(m_handleImage.m_pGraphics1!=NULL)           //  初始化 no.2{delete m_handleImage.m_pGraphics1;m_handleImage.m_pGraphics1=new Graphics(GetDC()->m_hDC);}elsem_handleImage.m_pGraphics1=new Graphics(GetDC()->m_hDC);SetRectTracker();   //no.3ReDraw();}if (m_pG!=NULL){delete m_pG;m_pG=NULL;}m_pG=new Graphics(GetDC()->m_hDC);}// TODO: 在此处添加消息处理程序代码}void NewImageView::OnBnClickedEnLarge(){// TODO: 在此添加控件通知处理程序代码if(m_pBmp){delete m_pBmp;m_pBmp=NULL;}m_fzoom*=1.25;ReDraw();InvalidateRect(m_ClientRect);}void NewImageView::SetImage(CString str){if(m_pBmp){delete m_pBmp;m_pBmp=NULL;}if(m_pImage){delete m_pImage;m_pImage=NULL;}m_pImage=Bitmap::FromFile(str);m_ImgH=m_pImage->GetHeight();m_ImgW=m_pImage->GetWidth();float fRateW=(float)m_ImgW/m_ClientRect.Width();float fRateH=(float)m_ImgH/m_ClientRect.Height();m_fRate=max(fRateH,fRateW);  if (m_pMemBmp)    {delete m_pMemBmp;m_pMemBmp=NULL;    } Rect rect(0,0,m_pImage->GetWidth(),m_pImage->GetHeight());m_pMemBmp=m_pImage->Clone(rect,m_pImage->GetPixelFormat());ReDraw();InvalidateRect(m_ClientRect);}void NewImageView::OnBnClickedButton4() //最佳{// TODO: 在此添加控件通知处理程序代码if(m_pBmp){delete m_pBmp;m_pBmp=NULL;}m_fzoom=1.0;m_Point.x=0;m_Point.y=0;m_PreP.x=0;m_PreP.y=0;ReDraw();InvalidateRect(m_ClientRect);}void NewImageView::OnBnClickedButton1() //缩小{// TODO: 在此添加控件通知处理程序代码if(m_pBmp){delete m_pBmp;m_pBmp=NULL;}m_fzoom/=1.25;ReDraw();InvalidateRect(m_ClientRect);}BOOL NewImageView::OnEraseBkgnd(CDC* pDC){// TODO: 在此添加消息处理程序代码和/或调用默认值return FALSE;return CFormView::OnEraseBkgnd(pDC);}void NewImageView::OnBnClickedButton3()  //原始{// TODO: 在此添加控件通知处理程序代码if(m_pBmp){delete m_pBmp;m_pBmp=NULL;}m_fzoom=m_fRate;ReDraw();InvalidateRect(m_ClientRect);}void NewImageView::OnBnClickedButton5() // 上一个图{// TODO: 在此添加控件通知处理程序代码CTreePathView * pTree=(CTreePathView* )(((CMainFrame *)AfxGetMainWnd())->m_wndSplitter.GetPane(0,0));CTreeCtrl & treeCtrl=pTree->GetTreeCtrl();HTREEITEM hItem=treeCtrl.GetSelectedItem();if (hItem!=NULL){HTREEITEMhItemP=treeCtrl.GetNextItem(hItem,TVGN_PREVIOUS);if (hItemP!=NULL){CString str;str=pTree->GetFullPath(hItemP);if (pTree->IsImage(str))SetImage(str);treeCtrl.SelectItem(hItemP);treeCtrl.SetFocus();InvalidateRect(m_ClientRect);}else{treeCtrl.SelectItem(hItem);treeCtrl.SetFocus();}}}void NewImageView::OnBnClickedButton6() //下一个{// TODO: 在此添加控件通知处理程序代码CTreePathView * pTree=(CTreePathView* )(((CMainFrame *)AfxGetMainWnd())->m_wndSplitter.GetPane(0,0));CTreeCtrl & treeCtrl=pTree->GetTreeCtrl();HTREEITEM hItem=treeCtrl.GetSelectedItem();if (hItem!=NULL){HTREEITEMhItemN=treeCtrl.GetNextItem(hItem,TVGN_NEXT);if (hItemN!=NULL){CString str;str=pTree->GetFullPath(hItemN);if (pTree->IsImage(str))SetImage(str);treeCtrl.SelectItem(hItemN);treeCtrl.SetFocus();InvalidateRect(m_ClientRect);}else{treeCtrl.SelectItem(hItem);treeCtrl.SetFocus();}}}void NewImageView::OnLButtonDown(UINT nFlags, CPoint point){// TODO: 在此添加消息处理程序代码和/或调用默认值if (!m_handleImage.m_bLock){m_LbtndownP=point;}else{  //  no.4.1m_handleImage.m_bleftUp=FALSE;m_handleImage.m_bleftDown=TRUE;CRect rect=m_handleImage.m_RectTracker1.m_rect;if(m_handleImage.m_RectTracker1.HitTest(point)>=0)  //{m_handleImage.m_leftBnDown=point;m_handleImage.m_btDownPoint.x=point.x-1;m_handleImage.m_btDownPoint.y=point.y-1;if(m_handleImage.headRectTraker!=NULL&&!m_handleImage.headRectTraker->rectLock.m_rect.IsRectEmpty())m_handleImage.DrawRectImage(m_handleImage.headRectTraker);}else{CPoint pos;::GetCursorPos(&pos);ScreenToClient(&pos);//pos.y=m_handleImage.m_RectTracker1.m_rect.TopLeft().y;if(pos.x<m_handleImage.m_RectTracker1.m_rect.TopLeft().x)pos.x=m_handleImage.m_RectTracker1.m_rect.TopLeft().x;if(pos.y<m_handleImage.m_RectTracker1.m_rect.TopLeft().y)pos.y=m_handleImage.m_RectTracker1.m_rect.TopLeft().y;m_handleImage.m_leftBnDown=pos;                       //当光标在图片外时,调整矩形的起始位置m_handleImage.m_btDownPoint.x=m_handleImage.m_leftBnDown.x-1;m_handleImage.m_btDownPoint.y=m_handleImage.m_leftBnDown.y-1;}}CFormView::OnLButtonDown(nFlags, point);}void NewImageView::OnMouseMove(UINT nFlags, CPoint point){// TODO: 在此添加消息处理程序代码和/或调用默认值if ((nFlags&MK_LBUTTON)==MK_LBUTTON)  {            if(!m_handleImage.m_bLock)  {SetCursor(AfxGetApp()->LoadCursor(IDC_CURSOR_HAND));m_Point.x=m_PreP.x+(point.x-m_LbtndownP.x);  m_Point.y=m_PreP.y+(point.y-m_LbtndownP.y);  ReDraw();RedrawWindow(m_ClientRect);  }else{ // no. 4.2//  if(m_handleImage.m_RectTracker1.HitTest(point)>=0){  SetCursor(AfxGetApp()->LoadStandardCursor(IDC_CROSS));  m_handleImage.m_movePoint=point;  m_handleImage.m_btDownSize.cx=point.x-m_handleImage.m_btDownPoint.x;  m_handleImage.m_btDownSize.cy=point.y-m_handleImage.m_btDownPoint.y;  Pen pen(Color(255,255,0,0),2);  int width_w=point.x-m_handleImage.m_leftBnDown.x;  int height_h=point.y-m_handleImage.m_leftBnDown.y;  m_handleImage.m_width_w=width_w;  m_handleImage.m_height_h=height_h;  CRect rect(m_handleImage.m_leftBnDown.x,m_handleImage.m_leftBnDown.y,m_handleImage.m_leftBnDown.x+m_handleImage.m_width_w,m_handleImage.m_leftBnDown.y+m_handleImage.m_height_h);  m_handleImage.DrawRectImageOnImageOne(rect);  m_handleImage.m_pGraphics1->DrawRectangle(&pen,m_handleImage.m_leftBnDown.x,m_handleImage.m_leftBnDown.y,width_w,height_h);//  }  }}  CFormView::OnMouseMove(nFlags, point);}void NewImageView::OnLButtonUp(UINT nFlags, CPoint point){// TODO: 在此添加消息处理程序代码和/或调用默认值if(m_pBmp==NULL)return CFormView::OnMouseMove(nFlags, point);    m_PreP=m_Point;if (m_handleImage.m_bLock)  // no.4.3{int width_w=m_handleImage.m_movePoint.x-m_handleImage.m_leftBnDown.x;int height_h=m_handleImage.m_movePoint.y-m_handleImage.m_leftBnDown.y;if(width_w>2&&height_h>2){m_handleImage.NewNode();Invalidate(FALSE);}m_handleImage.m_movePoint.x=-10; //将此点还原为最小值  m_handleImage.m_movePoint.y=-10;}CFormView::OnLButtonUp(nFlags, point);}void NewImageView::OnImageEnlagge(){// TODO: 在此添加命令处理程序代码AfxMessageBox(L"ADD");}BOOL NewImageView::PreTranslateMessage(MSG* pMsg){// TODO: 在此添加专用代码和/或调用基类/*if (WM_KEYFIRST<=pMsg->message&&pMsg->message<=WM_KEYLAST){HACCEL hAccel=m_hAccel;if (hAccel&&::TranslateAccelerator(GetForegroundWindow()->m_hWnd,hAccel,pMsg))return TRUE;}*/return CFormView::PreTranslateMessage(pMsg);}void NewImageView::OnTest(){AfxMessageBox(L"f9");// TODO: 在此添加命令处理程序代码}void NewImageView::OnBnClickedButton7()  //锁定图片{// TODO: 在此添加控件通知处理程序代码m_handleImage.m_bLock=!m_handleImage.m_bLock;if (m_handleImage.m_bLock){GetDlgItem(IDC_BUTTON7)->SetWindowText(_T("取消锁定"));}else{GetDlgItem(IDC_BUTTON7)->SetWindowText(_T("锁定图片"));}SetRectTracker();  //锁定时 重新确定no.3.2Invalidate(FALSE);if(m_handleImage.m_pGraphics1!=NULL)   //  实时更新绘图设备上下文环境{delete m_handleImage.m_pGraphics1;m_handleImage.m_pGraphics1=new Graphics(GetDC()->m_hDC);}elsem_handleImage.m_pGraphics1=new Graphics(GetDC()->m_hDC);}void NewImageView::SetRectTracker(){CRectTracker rectTracker1;int x,y,cx,cy; //橡皮筋的起始位置和长宽rectTracker1.Draw(GetDC());int nWidth = m_ImgW/m_fRate*m_fzoom;int nHeight = m_ImgH/m_fRate*m_fzoom;if(m_fzoom>1.0){x=m_ClientRect.TopLeft().x+m_Point.x;y=m_ClientRect.TopLeft().y+m_Point.y;cx=m_pBmp->GetWidth();cy=m_pBmp->GetHeight();}else{x=m_ClientRect.TopLeft().x+(m_ClientRect.Width()-nWidth)/2;y=m_ClientRect.TopLeft().y+(m_ClientRect.Height()-nHeight)/2;cx=m_pBmp->GetWidth();cy=m_pBmp->GetHeight();}//Graphics graphics(GetDC()->m_hDC);rectTracker1.m_rect.SetRect(x,y,x+cx,y+cy);m_handleImage.m_RectTracker1=rectTracker1;m_handleImage.AdjustAllRect();m_handleImage.ReSetLinePos();}


 

 

 

 

 

原创粉丝点击