GDI+学习之路8--图形容器
来源:互联网 发布:数据库中注释 编辑:程序博客网 时间:2024/06/08 18:46
图片状态(裁剪区域、变形、质量设置等)存储于Graphics对象中。GDI+ 允许您采用一个容器临时替换或者扩充一个Graphics对象的状态。调用Graphics对象的BeginContainer方法开始一个容器,直至调用EndContainer方法终止一个容器。在这期间,您对于属于该容器的Graphics对象进行的任何状态改变都不会覆盖掉Graphics对象现存的状态。
下面的例子在一个Graphics对象中创建一个容器。Graphics对象的世界变换是向右平移200个单位,而容器的世界变换是向下平移100个单位。
myGraphics.TranslateTransform(200.0f,0.0f);
myGraphicsContainer =myGraphics.BeginContainer();
myGraphics.TranslateTransform(0.0f, 100.0f);
myGraphics.DrawRectangle(&myPen, 0, 0, 50, 50);
myGraphics.EndContainer(myGraphicsContainer);
myGraphics.DrawRectangle(&myPen, 0,0, 50, 50);
注意,在前面的例子中, 置于BeginContainer和EndContainer调用之间的语句myGraphics.DrawRectangle(&myPen, 0, 0, 50, 50)产生的矩形和EndContainer调用之后的同样的语句产生了不同的2个矩形。应用于DrawRectangle调用的两种变换(水平平移200个单位和垂直平移100个单位)都在容器内部进行。下图显示了这两个矩形。
容器可以与容器嵌套。下面的例子在一个Graphics对象内创建一个容器,紧接着在前一个容器中再创建另一个容器。Graphics容器的世界变换是沿X轴平移100个单位然后沿Y轴平移80个单位。第一个容器的世界变换是旋转30度角。第二个容器的世界变换是沿X轴缩放2倍单位。在第二个容器中调用DrawEllipse方法。
myGraphics.TranslateTransform(100.0f,80.0f, MatrixOrderAppend);
container1 = myGraphics.BeginContainer();
myGraphics.RotateTransform(30.0f, MatrixOrderAppend);
container2 = myGraphics.BeginContainer();
myGraphics.ScaleTransform(2.0f, 1.0f);
myGraphics.DrawEllipse(&myPen, -30, -20, 60, 40);
myGraphics.EndContainer(container2);
myGraphics.EndContainer(container1);
注意,所有的变换都应用于第二个(最里面的)容器里面的DrawEllipse调用。同时注意,变换的顺序:首先缩放,然后是旋转,然后才是平移。最内层的变换最先被执行,最外层的变换最迟执行。
在容器内部(在BeginContainer和EndContainer调用之间)可以对Graphics对象的任意属性进行设置。例如,可以在容器内设置一个剪切区域。容器内的任何绘图操作都将被该容器的剪切区域所裁剪,同时也会被外层容器以及Graphics对象本身的剪切区域所裁剪。
关于属性的讨论已经很深入了,嵌套容器中的世界变换和裁剪区域。其他属性则由嵌套容器临时替换。例如,当您在一个容器中通过SmoothingModeAntiAlias设置了平滑模式后,在容器内部的任何绘图操作都将采用这个平滑模式,但是在EndContainer调用之后的绘图操作则采用BeginContainer调用之前的平滑模式。
再举个容器内部一个Graphics对象的世界变换的例子,假设立希望绘制一只眼睛然后将它放到若干脸部的不同位置。下面的例子将在坐标系统原点位置绘制一只眼睛。
void DrawEye(Graphics* pGraphics)
{
GraphicsContainer eyeContainer;
eyeContainer = pGraphics->BeginContainer();
Pen myBlackPen(Color(255, 0, 0, 0));
SolidBrush myGreenBrush(Color(255, 0, 128, 0));
SolidBrush myBlackBrush(Color(255, 0, 0, 0));
GraphicsPath myTopPath;
myTopPath.AddEllipse(-30, -50, 60, 60);
GraphicsPath myBottomPath;
myBottomPath.AddEllipse(-30, -10, 60, 60);
Region myTopRegion(&myTopPath);
Region myBottomRegion(&myBottomPath);
// Draw theoutline of the eye.
// The outline of the eye consists of two ellipses.
// The topellipse is clipped by the bottom ellipse, and
// the bottom ellipse is clipped by the top ellipse.
pGraphics->SetClip(&myTopRegion);
pGraphics->DrawPath(&myBlackPen, &myBottomPath);
pGraphics->SetClip(&myBottomRegion);
pGraphics->DrawPath(&myBlackPen, &myTopPath);
// Fill theiris.
// The iris isclipped by the bottom ellipse.
pGraphics->FillEllipse(&myGreenBrush, -10, -15, 20, 22);
// Fill thepupil.
pGraphics->FillEllipse(&myBlackBrush, -3, -7, 6, 9);
pGraphics->EndContainer(eyeContainer);
}
上面例子中的DrawEye函数接受一个Graphics对象地址,然后立即在该Graphics对象中创建一个容器。容器使得DrawEye函数内部的代码调用与在执行过程中的属性设置相脱离。例如,DrawEys函数内部代码设置了Graphics对象的剪切区域,但是当DrawEys将控制权返回给调用例程后,裁剪区域将恢复为DrawEye调用之前的状态。
下面的代码演示了绘制3个椭圆(脸),每个内部都有一只眼睛。
// Draw an ellipse with center at (100,100).
myGraphics.TranslateTransform(100.0f,100.0f);
myGraphics.DrawEllipse(&myBlackPen,-40, -60, 80, 120);
// Draw the eye at the center of the ellipse.
DrawEye(&myGraphics);
// Draw an ellipse with center at 200,100.
myGraphics.TranslateTransform(100.0f,0.0f, MatrixOrderAppend);
myGraphics.DrawEllipse(&myBlackPen,-40, -60, 80, 120);
// Rotate the eye 40 degrees, and drawit 30 units above
// the center of the ellipse.
myGraphicsContainer =myGraphics.BeginContainer();
myGraphics.RotateTransform(-40.0f);
myGraphics.TranslateTransform(0.0f, -30.0f, MatrixOrderAppend);
DrawEye(&myGraphics);
myGraphics.EndContainer(myGraphicsContainer);
// Draw a ellipse with center at(300.0f, 100.0f).
myGraphics.TranslateTransform(100.0f,0.0f, MatrixOrderAppend);
myGraphics.DrawEllipse(&myBlackPen,-40, -60, 80, 120);
// Stretch and rotate the eye, and drawit at the
// center of the ellipse.
myGraphicsContainer =myGraphics.BeginContainer();
myGraphics.ScaleTransform(2.0f, 1.5f);
myGraphics.RotateTransform(45.0f, MatrixOrderAppend);
DrawEye(&myGraphics);
myGraphics.EndContainer(myGraphicsContainer);
上例中,所有的椭圆都是采用DrawEllipse(&myBlackPen,-40, -60, 80, 120)调用绘制的,该语句将在坐标系统的原点位置绘制椭圆。通过设置Graphics对象的世界变换来将椭圆的工作区从左上角移开。该语句使得第一个椭圆在(100,100)的位置居中,使得第二个椭圆在第一个椭圆中心位置向右平移了100个单位。同样地,第三个椭圆的中心又在第二个椭圆的基础上向右平移了100个单位。
上例中的容器用于相对于给定椭圆中心对眼睛进行平移。第一只绘制于椭圆中心位置的眼睛没有任何变换,因此没有将DrawEye调用放到容器中。第二只眼睛旋转40度后又相对于椭圆中心向上平移了30个单位,因此DrawEye函数调用和变换等操作是在容器内部进行的。第三个眼睛进行了缩放、旋转操作然后绘制于椭圆中心位置。与第二只眼睛类似的,DrawEye函数调用和变换等操作也是置于容器内部的。
- GDI+学习之路8--图形容器
- GDI+学习之路8--图形容器
- GDI+学习之路8--图形容器
- 图形之GDI
- GDI+学习之路3--线条、曲线和图形(一)
- GDI+学习之路4--线条、曲线和图形(二)
- GDI+学习之路5--线条、曲线和图形(三)
- GDI+学习之路3--线条、曲线和图形(一)
- GDI+学习之路4--线条、曲线和图形(二)
- GDI+学习之路5--线条、曲线和图形(三)
- C#学习之GDI + 图形编程基础(一)
- C#学习之GDI + 图形编程基础(二)
- C#学习笔记之使用GDI绘制简单的图形
- 安卓高手之路之 GDI图形引擎篇
- 图形库比较:GDI,CxImage,GDI+之比较
- GDI图形的总结 (学习中)
- GDI学习笔记 输出文字与图形
- GDI编程之七、图形编程实例
- [转]虚拟机安装详细图解教程及使用教程
- experiment @ lzptc ,2nd_term_6
- jsp导出Excel,Word文件几种方法
- poj 3928 Ping pong(离散化+树状数组)
- 线程模型
- GDI+学习之路8--图形容器
- 炎炎夏日,代码清火----给VisualStudio换一个清凉的主题
- experiment @ lzptc ,2nd_term_exp3
- Linux下的线程技术
- jquery中的trigger和triggerHandler区别
- 文件打包源代码
- C++中string相关函数
- .net 调用java WebService简单教程
- 八、Hibernate一对一唯一外键关联(单向关联)