今天小编给大家分享一下C#中怎么使用GDI绘制圆弧及圆角矩形等比缩放的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。
GDI+中对于圆弧的绘制,是以给定的长方形(System.Drawing.Rectangle
结构)为边界绘制的椭圆的一部分形成的圆弧。绘制的圆弧的中心为长方形内切椭圆的圆心(如果是正方形,则正方形的中心是内切圆的圆心)
Graphics
对象的DrawArc()
方法用于绘制圆弧线段;GraphicsPath
对象的AddArc()
方法用于绘制圆弧路径。
以DrawArc
为例,参数为:DrawArc (System.Drawing.Pen pen, System.Drawing.Rectangle rect, float startAngle, float sweepAngle)
,绘制一段弧线,它表示 Rectangle 结构指定的椭圆的一部分。
pen 为画笔对象。
rect 包含圆弧的长方体结构。
startAngle 圆弧绘制的开始角度。
sweepAngle 从 startAngle 角度到弧线的结束点沿顺时针方向度量的角(以度为单位),即从startAngle开始绘制弧线转动的角度。
新建Winform项目GDIForArc
,测试和演示弧形绘制的效果。
直接看下面的代码,分别绘制矩形对应的四个角的弧形(1/4圆),可以很直观的看到圆弧的绘制及与长方体的关系:
protected override void OnPaint(PaintEventArgs e) { Graphics g = e.Graphics; Pen pn = new Pen(Color.Blue,5); Rectangle rect = new Rectangle(50, 50, 150, 150); g.DrawRectangle(pn, rect); Rectangle rect2 = new Rectangle(300, 50, 150, 350); g.DrawRectangle(pn, rect2); // 红色 0-90deg的圆弧 pn.Color = RedColor; g.DrawArc(pn, rect, 0, 90); g.DrawArc(pn, rect2, 0, 90); // 黑色 90-180deg的圆弧 pn.Color = BalckColor; g.DrawArc(pn, rect, 90, 90); g.DrawArc(pn, rect2, 90, 90); // 绿色 180-270deg的圆弧 pn.Color = GreenColor; g.DrawArc(pn, rect, 180, 90); g.DrawArc(pn, rect2, 180, 90); // 粉色 270-360deg的圆弧 pn.Color = HotPink; g.DrawArc(pn, rect, 270, 90); g.DrawArc(pn, rect2, 270, 90); }
GDI+中绘图系统中顺时针方向为旋转正方向,水平向右方向为x轴正方向,垂直向下为y轴正方向。
通过Rectangle结构内的四个圆弧,可以组合成四个圆角,从而可以进一步实现圆角长方体、圆形等图形。
如下,是使用这个方式绘制的圆角矩形。
需要注意的点:
线条连接时的1像素问题,很多时候会出现1像素的间隔,并没有完全闭合连接,需要额外处理
Pen.LineJoin
指定线条连接点的模式
// 绘制圆角矩形 pn.Color = Color.MediumVioletRed; // 指定连接处的连接点 pn.LineJoin = LineJoin.Round; Rectangle roundRect = new Rectangle(500, 50, 150, 80); var radius = 20; var R = radius * 2; Rectangle arcRect = new Rectangle(roundRect.X, roundRect.Y, R, R); // 左上角 g.DrawArc(pn, arcRect, 180, 90); // 右上角 arcRect.X = roundRect.Right - R; g.DrawArc(pn, arcRect, 270, 90); // 右下角 arcRect.Y = roundRect.Bottom - R; g.DrawArc(pn, arcRect, 0, 90); // 左下角 arcRect.X = roundRect.Left; g.DrawArc(pn, arcRect, 90, 90); #region 单独绘制线条,需要处理1像素间隔问题,且连接处不平滑 g.DrawLine(pn, roundRect.X + radius, roundRect.Y, roundRect.Right - radius + 1, roundRect.Y); g.DrawLine(pn, roundRect.Right, roundRect.Y + radius, roundRect.Right, roundRect.Bottom - radius + 1); g.DrawLine(pn, roundRect.Right - radius + 1, roundRect.Bottom, roundRect.Left + radius, roundRect.Bottom); g.DrawLine(pn, roundRect.Left, roundRect.Bottom - radius + 1, roundRect.Left, roundRect.Y + radius); #endregion
根据上面绘制矩形的思路,想着同样实现一个按照等比缩放绘制内部圆角矩形的方式。主要思路是,指定一个缩放比例,让外部的矩形宽高、位置、圆角绘制的半径、直径等对应等比缩放并计算其值。
然后就是圆角矩形的绘制思路。
#region 等比缩放的绘制圆角矩形 //// 等比缩放,绘制内层圆角矩形 var scale = 0.8f; var radiusScale = radius * scale; var RScale = radiusScale * 2; var innerRoundRect = new RectangleF(roundRect.X + (roundRect.Width - roundRect.Width * scale) / 2, roundRect.Y + (roundRect.Height - roundRect.Height * scale) / 2, roundRect.Width * scale, roundRect.Height * scale); var arcRectScale = new RectangleF(innerRoundRect.X, innerRoundRect.Y, RScale, RScale); //var scale = 0.8f; //var radiusScale = Convert.ToInt32(radius * scale); //var RScale = radiusScale * 2; //var width = Convert.ToInt32(roundRect.Width * scale); //var height = Convert.ToInt32(roundRect.Height * scale); //var innerRoundRect = new Rectangle(roundRect.X + (roundRect.Width - width) / 2, roundRect.Y + (roundRect.Height - height) / 2, width, height); //var arcRectScale = new Rectangle(innerRoundRect.X, innerRoundRect.Y, RScale, RScale); pn.Color = Color.MediumPurple; arcRectScale.X = innerRoundRect.X; arcRectScale.Y = innerRoundRect.Y; // 左上角 g.DrawArc(pn, arcRectScale, 180, 90); g.DrawLine(pn, innerRoundRect.X + radiusScale, innerRoundRect.Y, innerRoundRect.Right - radiusScale + 1, innerRoundRect.Y); // 右上角 arcRectScale.X = innerRoundRect.Right - RScale; g.DrawArc(pn, arcRectScale, 270, 90); g.DrawLine(pn, innerRoundRect.Right, innerRoundRect.Y + radiusScale, innerRoundRect.Right, innerRoundRect.Bottom - radiusScale + 1); // 右下角 arcRectScale.Y = innerRoundRect.Bottom - RScale; g.DrawArc(pn, arcRectScale, 0, 90); g.DrawLine(pn, innerRoundRect.Right - radiusScale + 1, innerRoundRect.Bottom, innerRoundRect.Left + radiusScale, innerRoundRect.Bottom); // 左下角 arcRectScale.X = innerRoundRect.Left; g.DrawArc(pn, arcRectScale, 90, 90); g.DrawLine(pn, innerRoundRect.Left, innerRoundRect.Bottom - radiusScale + 1, innerRoundRect.Left, innerRoundRect.Y + radiusScale); #endregion
去掉外层圆角矩形的直线,效果如下:
直接计算比例的问题在于,由于矩形长宽大小的不同,计算出来内部(或外部)矩形的缩小或增大的量会不同,原则上,应该是长宽方向上缩小固定的量(类似边框在长宽方向时,边框的大小都是一样的)。因此,最好取其中一个值。
缩小或增大的矩形的圆角半径是否应该对应缩放?这是一直没有很好处理的问题,如果缩小放大的变化不大,则没有太大区别,如果比较大,圆角半径最好保持不变(上例代码为圆角半径也跟着缩放的例子)
Inflate()
可分为实例方法和静态方法,它是专门用于缩放矩形的长宽指定的量的方法,而不是长宽不对等的比例计算。
推荐使用它加上圆角半径不变的方式,计算内层或外层圆角矩形。
Inflate的使用代码如下,其他不变的代码部分不再列出。
var inflateRect = Rectangle.Inflate(roundRect, -8, -8); // inflateRect.Inflate(-8, -8); // 实例方法,长宽缩小或放大指定的量,改变的实例本身 // others
以上就是“C#中怎么使用GDI绘制圆弧及圆角矩形等比缩放”这篇文章的所有内容,感谢各位的阅读!相信大家阅读完这篇文章都有很大的收获,小编每天都会为大家更新不同的知识,如果还想学习更多的知识,请关注亿速云行业资讯频道。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。