GDI+学习及代码总结之.docx
《GDI+学习及代码总结之.docx》由会员分享,可在线阅读,更多相关《GDI+学习及代码总结之.docx(10页珍藏版)》请在冰豆网上搜索。
![GDI+学习及代码总结之.docx](https://file1.bdocx.com/fileroot1/2023-5/29/d7e5b69a-5596-4711-80f6-f6b7bc9e0df5/d7e5b69a-5596-4711-80f6-f6b7bc9e0df51.gif)
GDI+学习及代码总结之
GDI+学习及代码总结之
GDI+学习及代码总结之------区域在GDI+中对于区域的部分基本上使用了GDI的区域构造函数与合并方法所以我们先看看GDI中的区域是如何构造与操作的。
GDI中区域构建与操作
一、基本函数一、基本函数
创建矩形区域:
创建矩形区域:
HRGNCreateRectRgnIndirect(CONSTRECT_lprc);
HRGNCreateRectRgn(
intnLeftRect,
//left点坐标(_)
intnTopRect,
//top点坐标值(Y)
intnRightRect,
//right点坐标值(_)
intnBottomRect
//bottom点坐标值(Y)
);
创建椭圆区域:
创建椭圆区域:
HRGNCreateEllipticRgnIndirect(
CONSTRECT_lprc
//boundingrectangle
);
HRGNCreateEllipticRgn(
intnLeftRect,
//_-coordofupper-leftcornerofrectangle
intnTopRect,
//y-coordofupper-leftcornerofrectangle
intnRightRect,
//_-coordoflower-rightcornerofrectangle
intnBottomRect
//y-coordoflower-rightcornerofrectangle
);
创建多边形区域:
创建多边形区域:
HRGNCreatePolygonRgn(
CONSTPOINT_lppt,
//arrayofpoints
intcPoints,
//numberofpointsinarray
intfnPolyFillMode
//polygon-fillingmode
);
合并区域:
合并区域:
intbineRgn(
HRGNhrgnDest,
//handletodestinationregion
HRGNhrgnSrc1,
//handletosourceregion
HRGNhrgnSrc2,
//handletosourceregion
intfnbineMode
//regionbiningmode
);
对于binMode有四个取值:
RGN_COPY:
:
原样复制hrgnSrc1中的区域一般不用这个没太大意义;RGN_AND:
:
合成的区域是hrgnSrc1和hrgnSrc2的重叠部分;RGN_DIFF:
:
合成的区域是hrgnSrc1中不包含hrgnSrc2的部分;RGN_OR:
:
合成的区域同时包含hrgnSrc2和hrgnSrc2;RGN__OR:
:
合成的区域同时包含hrgnSrc2和hrgnSrc2但不包含hrgnSrc2和hrgnSrc2的重叠部分;
区域的句柄可用的4个绘图函数:
FillRgn(hdc,hRgn,hBrush);//类似FillRect
FrameRgn(hdc,hRgn,hBrush,_Frame,yFrame);//类似FrameRect
InverRgn(hdc,hRgn);//类似InvertRect
PaintRgn(hdc,hRgn);//用设备描述表中的当前画刷填充所指的区域。
所有这些函数都假设区域是逻辑坐标定义的删除一个区域
DeleteObject(hRgn);
//Windows的2个作用于区域而不是矩形的函数
InvalidateRgn(hwnd,hRgn,bErase);//类似于InvalidateRect
ValidateRgn(hwnd,hRgn);//类似于ValidateRect
上面两个函数也会以WM_PAINT消息作出反应剪裁区域首先是创建剪裁区域
SelectObject(hdc,hRgn);
SelectClipRgn(hdc,hRgn);
上面两个函数都是将一个区域选进设备描述表来创建自己的剪裁区域这个剪裁区域使用设备坐标。
对剪裁区域的操作函数:
E_cludeClipRect用于将一个矩形从剪裁区域里排除掉
IntersectClipRect用于创建一个新的剪裁区域他是前一个剪裁区域与一个矩形的交
集
OffsetClipRgn用于将剪裁区域移动到客户区的另一部分
注意:
GDI会为剪裁区域创建一个副本所以在将新创建的区域选进设备描述表后用户可以删除这个区域。
bineRgn(hDestRgn,hSrcRgn1,hSrcRgn2,ibine);中使用的3个区域句柄必须都是有效的即都要是创建了的。
在调用bineRgn函数后源区域即可以删除了删除不会影响新合成的区域
看在GDI中使用区域函数的一个示例:
(区域抠图)
原理:
先用图片大小的矩形构造一个目的区域所以这个区域的大小就是整个图片的大小然后从图片的左上角(00)开始按照从上到下、从左到右的顺序形成长宽都为1的矩形(就是一个像素大小)如果矩形中的背景是白色将之从目的区域中去除所以最终剩下的区域就是主画面的区域了。
这就是“抠”出主界面区域的关键思路所在。
先看下原来的图片:
抠图代码:
Bitmapphoto(L“wlh.bmp”);
//得到相框尺寸
INTiWidth=photo.GetWidth();
INTiHeight=photo.GetHeight();
graphics.DrawImage(&;photo,0,0,iWidth,iHeight);
//将绘图平面右移设置新的绘图原点
graphics.TranslateTransform(iWidth+10,0);
Colorcolor,colorTemp;
HRGNendRgn=CreateRectRgn(0,0,iWidth,iHeight);
//依次获取相框的每一个相素
for(intiRow=0;iRow<iHeight;iRow++){
for(intiColumn=0;iColumn<iWidth;iColumn++){
photo.GetPi_el(iColumn,iRow,&;color);
//如果像素为白色从原有区域中去除当前区域点
if(color.GetR()==255&;&;color.GetG()==255&;&;color.GetB()==255){
HRGNtempRgn=CreateRectRgn(iColumn,iRow,iColumn+1,iRow+1);
bineRgn(endRgn,tempRgn,endRgn,RGN__OR);
}//if--end
}
}
//创建GDI+区域变量
Regionfillrgn(endRgn);
graphics.FillRegion(&;SolidBrush(Color:
:
Green),&;fillrgn);
GDI+中的区域构建与操作一、构造函数(Region):
):
Region()
Region(path)//从路径构建
Region(hRgn)//从GDI中的HRGN句柄构建
Region(Rect&;rect)//从矩形构建
Region(RectF&;rect)
Region(regionData,size)//使用区域数组信息创建
这里有两个非常重要的构建函数要说明一下:
Region(hRgn)//从GDI中的HRGN句柄构建
Region(Rect&;rect)//从矩形构建
对于对于Region(hRgn):
我们很多时候可以GDI中区域函数构建区域;然后使用这个构建函数构建Regin变量然后使用GDI+中的函数fillRegion啥啥的;对于对于Region(Rect):
Region类只提供了这么一个矩形构造函数没有GDI中的椭圆、多边形区域的构建方法所以当我们构建椭圆、多边形区域时就是使用GDI了。
二、区域操作(构建区域)
二、区域操作(构建区域)
对于GDI中的操作我们知道bineRgn的最后一个参数可以实现对区域的RGN_AND、RGN_DIFF、RGN_OR、RGN__OR在GDI+中Regin类中也有对区域的操作函数同样实现了GDI中的区域操作功能它们分别是:
Region:
:
Intersect(region)//求区域A和区域B的共有部分(交集)
Region:
:
Union(region)//求同时包含区域A和区域B的区域(并集)
Region:
:
_or(region)//求不包含区域A和区域B相交部分的区域(异并集又称为对称差)
Region:
:
plement(region)//求区域B中不含区域A的区域(A的补集)
Region:
:
E_clude(region)//求区域A中不含区域B的区域(B的补集)
//异并集(集合的对称差):
设A、B为任意两个集合A和B的对称差为集合S其元素或属于A或属于B但不能即属于A又属于B这样的集合S称为集合A与B的对称差
简单的看一个示例吧(异并集的)
Regionrgn1(RectF(25,10,50,100));
Regionrgn2(RectF(0,50,100,30));
Penpen1(Color:
:
Red,2);
Penpen2(Color:
:
Blue,2);
SolidBrushbrush(Color:
:
Green);
rgn1._or(&;rgn2);
graphics.TranslateTransform(20,0);//转变绘制原点这里这句并不是必须的我只是为了让大家记住这个函数
graphics.FillRegion(&;brush,&;rgn1);
graphics.DrawRectangle(&;pen1,RectF(25,10,50,100));
graphics.DrawRectangle(&;pen2,RectF(0,50,100,30));
三、用矩形表示区域三、用矩形表示区域
对于特定的区域我们都可以使用多个矩形来表示其大致形状。
事实上如果矩形足够小一定数量的矩形就能够精确表示区域的形状也就是说一定数量的矩形所合成的形状也可以代表区域的形状。
Region类的GetRegionScans函数实现了获取组成区域的矩形集的功能其调用格式如下:
GetRegionScans(Matri__matri_,Rect_rects,INT_count)
GetRegionScans(Matri__matri_,RectF_rects,INT_count)
参数:
matri_:
[in]绘制平面上的坐标变换矩阵rects:
[out]代表矩形集的数组count:
[out]矩形集的数量该值可以通过GetRegionScansCount函数获取。
示例:
SolidBrushsolidBrush(Color:
:
Red);
Penpen(Color:
:
Green);
GraphicsPathpath;
Matri_matri_;
Rect_rects=NULL;
INTcount=0;
path.AddEllipse(10,0,80,120);
RegionpatchRegion(&;path);
graphics.FillRegion(&;solidBrush,&;patchRegion);
graphics.GetTransform(&;matri_);
count=patchRegion.GetRegionScansCount(&;matri_);
//为矩形集分配空间
rects=(Rect_)malloc(count_sizeof(Rect));
patchRegion.GetRegionScans(&;matri_,rects,&;count);
graphics.TranslateTransform(140,0);
for(INTj=0;j<count;j++){
graphics.DrawRectangle(&;pen,rects[j]);
}
free(rects);
四、击中测试区域(判断点是否在区域内)
四、击中测试区域(判断点是否在区域内)
击中测试(HitTest)简单地说就是判断一个点是否位于指定的区域内。
Region类的成员函数IsVisible提供了这样一个功能。
而且还提供了扩展:
不仅可以测试一个点是否位于指定的区域中还可以测试两矩形区域是存否在交集。
IsVisible的调用格式为:
IsVisible(Point&;point,Graphics_g)
IsVisible(PointF&;point,Graphics_g)
IsVisible(Rect&;rect,Graphics_g)
IsVisible(RectF&;rect,Graphics_g)
IsVisible(INT_,INTy,Graphics_g)
IsVisible(REAL_,REALy,Graphics_g)
IsVisible(INT_,INTy,INTwidth,INTheight,Graphics_g)
IsVisible(REAL_,REALy,REALwidth,REALheight,Graphics_g)
参数说明:
g:
[]绘图平面;point:
[in]点坐标;rect及及_,y,width,height:
[in]定义欲测试的矩形区间;
示例:
考虑这样一个应用当鼠标移动到指定区域时输出字符串”;yes”否则擦掉这个字符串(擦除操作是用填充背景颜色完成的);在View类中的OnMouseMove(UINTnFlags,CPointpoint)添加如下代码:
Graphicsgraphics(this-GetDC()-m_hDC);
FontFamilyff(L“Arial”);
Fontfont(&;ff,15,FontStyleRegular,UnitPi_el);
Regionrgn(RectF(10,10,100,200));
boolbinrgn=rgn.IsVisible(point._,point.y,&;graphics);
graphics.DrawRectangle(&;Pen(Color:
:
Green,2),RectF(10,10,100,200));
if(binrgn){
graphics.DrawString(L“yes”,-1,&;font,PointF(200,10),&;SolidBrush
(Color:
:
Red));
}else{
graphics.FillRectangle(&;SolidBrush(Color:
:
White),RectF(200,10,100,100));
}