GDI+高级编程 - 图文(3)

2019-08-03 13:52

13.2 区域

区域(region)是由若干几何形状所构成的一种封闭图形,主要用于复杂图形的绘制、图形输出的剪裁和鼠标击中的测试等。最简单也是最常用的区域是矩形,其次是椭圆和多边形以及它们的组合。这些也正是GDI所支持的区域类型。

GDI+中的区域是一种显示表面的范围(an area of the display surface),可以是任意形状(的图形的组合),边界一般为路径。除了上面所讲的矩形、椭圆、多边形之外,其边界还可以含直线、折线、弧、贝塞尔曲线和基样条曲线等开图形,其内容还可以包含饼、闭贝塞尔曲线和基样条曲线等闭图形。

在GDI+中,区域所对应的类是Region,它是一个独立的类(没有基类,也没有派生类)。但是它有若干相关的类,如各种图形类和图形路径类等。

13.2.1 构造函数

Region类有6个构造函数:

Region(VOID); // 创建一个空区域

Region(const Rect &rect); // 创建一个整数型矩形区域 Region(const RectF &rect); // 创建一个浮点数型矩形区域 Region(const GraphicsPath *path); // 由图形路径来创建区域

Region(const BYTE *regionData, INT size); // 由(另一)区域的数据构造区域 Region(HRGN hRgn); // 由GDI的区域句柄构造区域

其中,创建矩形区域最简单,由路径创建区域最常用。

13.2.2 其他方法

区域类的其他方法有(其中的图形对象g也用于坐标计算):

Region *Clone(VOID); // 克隆(复制) // 判断本区域是否与另一区域region相等:

BOOL Equals(const Region *region, const Graphics *g) const; BOOL IsEmpty(const Graphics *g) const; // 判断区域是否为空 Status MakeEmpty(VOID); // 清空区域

11

BOOL IsInfinite(const Graphics *g) const; // 判断区域是否无限 Status MakeInfinite(VOID); // 使区域成为无限的

Status GetBounds(Rect *rect, const Graphics *g) const; //获取外接(包)矩形 Status GetBounds(RectF *rect, const Graphics *g) const; //获取外接(包)浮点矩形 UINT GetDataSize(VOID) const; // 获取区域数据的字节大小 // 获取区域的二进制数据,可以用于创建其他区域:

Status GetData(BYTE *buffer, UINT bufferSize, UINT *sizeFilled = NULL) const; UINT GetRegionScansCount(const Matrix *matrix) const; // 获取区域的矩形逼近表示 Status GetRegionScans(const Matrix *matrix, Rect *rects, INT *count) const; Status GetRegionScans(const Matrix *matrix, RectF *rects, INT *count) const; Status Translate(INT dx, INT dy); // 平移区域 Status Translate(REAL dx, REAL dy);

Status Transform(const Matrix *matrix); // 变换区域

Status GetLastStatus(VOID); // 获取最后一次区域操作的状态,成功返回Ok HRGN GetHRGN(const Graphics *g) const; // 获取区域所对应的GDI区域的句柄 区域类还有集合运算和区域测试等方法,将在下面分别介绍。

13.2.3 区域的集合运算

? 并(union)

Status Union(const Region *region); // 与另一区域的并

Status Union(const Rect[F] &rect); // 与另一整数[浮点数]型矩形的并 Status Union(const GraphicsPath *path); // 与另一路径的并 ? 交(intersect):Status Intersect(重载和参数同并的); ? 余(exclude):Status Exclude(重载和参数同并的); ? 补(complement):Status Complement(重载和参数同并的); ? 异或(xor):Status Xor(重载和参数同并的); 例如(参见图13-7):

SolidBrush textBrush(Color::Black); Font font(L\宋体\

12

StringFormat stringFormat;

stringFormat.SetAlignment(StringAlignmentCenter); Point points[] = {Point(100, 0), Point(122, 69),

Point(195, 69), Point(137, 111), Point(159, 181), Point(100, 138), Point(41, 181), Point(63, 111), Point(5, 69), Point(78, 69)};

GraphicsPath path;

path.AddPolygon(points, 10);

Region *pRgn, rgnRect(Rect(0, 50, 200, 80)); SolidBrush *pBrush, gbrush(Color::Green),

tbrush(Color::Turquoise);

CString strs[] = {L\原集\并集\交集\余集\补集\

L\异或集\

PointF pts[] = {PointF(0.0f, 0.0f), PointF(210.0f, 0.0f),

PointF(210.0f, 0.0f), PointF(-420.0f, 220.0f), PointF(210.0f, 0.0f), PointF(210.0f, 0.0f)};

Graphics graph(pDC->m_hDC); for (int i = 0; i < 6; i++) {

pRgn = new Region(&path); switch (i) { }

if (i == 0) pBrush = &gbrush; else pBrush = &tbrush; graph.TranslateTransform(pts[i].X, pts[i].Y); graph.FillRegion(pBrush, pRgn); if (i == 0) graph.FillRegion(

13

case 1: pRgn->Union(&rgnRect); break; case 2: pRgn->Intersect(&rgnRect); break; case 3: pRgn->Exclude(&rgnRect); break; case 4: pRgn->Complement(&rgnRect); break; case 5: pRgn->Xor(&rgnRect); break;

}

&SolidBrush (Color(128, 255, 0, 0)), &rgnRect);

graph.DrawString(strs[i], -1, &font, PointF(100, 190),

&stringFormat, &textBrush);

delete pRgn;

图13-7 区域的集合运算

又例如(抠图,参见图13-8。注意:图像不能太大,背景必须为单色):

Bitmap bmp(L\米老鼠和唐老鸭.bmp\Graphics graph(pDC->m_hDC); graph.DrawImage(&bmp, 0, 0);

int w = bmp.GetWidth(), h = bmp.GetHeight(); Region rgn(Rect(0, 0, w, h)); Color col, col0;

bmp.GetPixel(0, 0, &col0); // 获取背景色 ARGB argb0 = col0.GetValue(); for (int i = 0; i < w; i++) {

for (int j = 0; j < h; j++) {

bmp.GetPixel(i, j, &col); if (col.GetValue() == argb0) {

Region pixelRgn(Rect(i, j, 1, 1)); // 单像素矩形 rgn.Exclude(&pixelRgn); // 挖去

14

}

}

}

graph.TranslateTransform(REAL(w), 0.0f);

graph.FillRegion(&SolidBrush(Color::Green), &rgn); // 容易溢出

图13-8 抠图

为了防止调用FillRegion方法造成堆栈溢出,必须减少区域的复杂度。解决办法之一是,不再每次去一个点,而是一次去一个(垂)直线段,则复杂度会减少一到两个数量级。从而可以避免溢出,代码大家可以自己去写。

13.2.4 击中测试

区域类的下列方法用于复杂图形的击中测试(其中的图形对象g用于坐标计算):

// 点是否在区域内

BOOL IsVisible(INT x, INT y, const Graphics *g) const; // 整数点坐标 BOOL IsVisible(const Point &point, const Graphics *g) const; // 整数点 BOOL IsVisible(REAL x, REAL y, const Graphics *g) const; // 浮点数点坐标 BOOL IsVisible(const PointF &point, const Graphics *g) const; // 浮点数点 // 矩形是否在区域内

// 整数左上角坐标与高宽

BOOL IsVisible(INT x, INT y, INT width, INT height, const Graphics *g) const; BOOL IsVisible(const Rect &rect, const Graphics *g) const; // 整数矩阵

// 浮点数左上角坐标与高宽

BOOL IsVisible(REAL x, REAL y, REAL width, REAL height, const Graphics *g) const; BOOL IsVisible(const RectF &rect, const Graphics *g) const; // 浮点矩阵

15


GDI+高级编程 - 图文(3).doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:中国铜管市场及投资调研报告目录

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: