弧形图形质量 [英] Arc graphic quality
问题描述
回到这里.有什么方法可以提高电弧的质量吗?
我正在使用e.Graphics.SmoothingMode = SmoothingMode.AntiAlias
Back here. Is there any way to improve the quality of the Arc?
I'm using e.Graphics.SmoothingMode = SmoothingMode.AntiAlias
这是创建圆弧的代码:
using (GraphicsPath gp = new GraphicsPath())
{
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
gp.Reset();
gp.AddPie(_OuterRectangle, (float)_Properties.Origin, (float)_Properties.GaugeType);
gp.Reverse();
gp.AddPie(_InnerRectangle, (float)_Properties.Origin, (float)_Properties.GaugeType);
gp.Reverse();
pArea.SetClip(gp);
using (Pen oPen = new Pen(this.ForeColor, 2f))
{
e.Graphics.DrawPath(oPen, gp);
}
e.Graphics.SetClip(ClientRectangle);
}
谢谢.
我做了LarsTech提出的建议,现在质量很完美,但是我没有所需的身材:
I've did what LarsTech proposed and now the quality is perfect, but I'm not having the figure I need:
- OuterRectangle :是ClientRectangle区域,我正在对其进行操作以使Width和Height的长度相同;
- InnerRectangle :是OuterRectangle的ClientRectangle区域ergo的2/3;
-
属性.来源:是圆弧开始的角度.我在枚举器中将其作为基数,北为270,东为0,
所以.如果是数字,则为西南,为135度;
- OuterRectangle: is the ClientRectangle area, that I'm manipulating it to make Width and Height the same lenght;
- InnerRectangle: is 2/3ths of the ClientRectangle area, ergo, of the OuterRectangle;
Properties.Origin: is the angle where the arc starts. I have it in an enumerator as Cardinal Points, where North is 270, East is 0,
and so. In case of the figure, is SouthWest, 135 degrees;
Properties.GaugeType :是另一个枚举器,它表示是否Complete = 360,Half = 180,Quarter = 90,这样我就可以确定扫角.如果数字是ThreeQuarter,则为270度.
Properties.GaugeType: is another enumerator that says if is Complete = 360, Half = 180, Quarter = 90, so with that I can determine the sweep angle. In case of the figure is ThreeQuarter, 270 degrees.
推荐答案
问题:
裁剪当前图形的区域时( Graphics.SetClip 方法),由于 Graphics.SmoothingMode = SmoothingMode.AntiAlias
产生的抗锯齿效果消失了,因此,最终的图形质量也会下降.
The problem:
When clipping a region of the current Graphics (Graphics.SetClip method), the resulting drawing loses quality, because the antialiasing effect generated by Graphics.SmoothingMode = SmoothingMode.AntiAlias
is lost.
一种可能的解决方案是避免剪切由用于设计弧的GraphicsPath
定义的区域(
A possible solution is to avoid clipping the region defined by the GraphicsPath
used to design the arcs (GraphicsPath.AddPie method); this, however, leaves the lines of the Pie visible, compromising the shape.
另一种解决方案是使用画布"的背景色在圆弧的中心绘制一个省略号.由于弧线是使用两个矩形绘制的,因此我们可以使用内部矩形将其充气( Rectangle.Inflate 方法)(通常是用于ouline的Pen大小的一部分-Pen.Width / 2
-).
Another solution is to draw an ellipsis in the center of the arcs using the background color of the Canvas. Since the arcs are drawn using two rectangles, we can use the inner rectagle, inflate it (Rectangle.Inflate method) as needed (a fraction - Pen.Width / 2
- of the Pen size used for the ouline, usually).
这允许删除由GraphicsPath
形状生成的伪像,并在形状的中心绘制一些其他图形内容.
This allows to delete the artifacts generated by the GraphicsPath
shapes and to draw some other graphics content in the center of the shapes.
例如,使用不同的画笔:
For example, using different Brushes:
LinearGradientBrush HatchBrush TextureBrush
当然,还有其他方法可以达到相同的结果.我们可以使用 GraphicsPath.AddArc绘制圆弧方法,提取或计算弧的第一个点和最后一个点,并用它们绘制两条线(
Of course there are other methods to achieve the same result. We could draw the Arcs using the GraphicsPath.AddArc method, extract or calculate the first and last points of the Arcs and use them to draw two lines (GraphicsPath.AddLine) that will close the figures.
但是,由于我们要在圆弧的中心绘制不同的图形对象,因此这些对象将始终覆盖中心区域.
But, since we want to draw different graphics objects in the center of the arcs, these objects will cover the center area anyway.
如何使用此代码:
- 在表单中,添加一个 TrackBar (在此处称为
tbarSpeed
) - 添加尺寸为
(200, 200)
的面板(称为Canvas
).使用此处提供的自定义面板"控件,该控件在其构造函数中添加了一些ControlStyles
.这样可以避免闪烁和伪影 - 连接TrackBar
tbarSpeed_Scroll
事件和面板Canvas_Paint
事件.
- In a Form, add a TrackBar (called
tbarSpeed
, here) - Add a Panel (called
Canvas
), with Size(200, 200)
. Use the Custom Panel control provided here, which adds someControlStyles
in its costructor. This will avoid flickering and artifacts - Wire up the TrackBar
tbarSpeed_Scroll
event and the PanelCanvas_Paint
event.
using System.Drawing;
using System.Drawing.Drawing2D;
float GaugeValue = 88.0f;
float GaugeSweepAngle = 270.0f;
float GaugeStartAngle = 135.0F;
private void Canvas_Paint(object sender, PaintEventArgs e)
{
Control canvas = sender as Control;
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
Rectangle outerRectangle = new Rectangle(10, 10, 180, 180);
Rectangle innerRectangle = new Rectangle(30, 30, 140, 140);
Rectangle blendRectangle = new Rectangle(10, 10, 180, 160);
PointF innerCenter = new PointF(outerRectangle.Left + (outerRectangle.Width / 2),
outerRectangle.Top + (outerRectangle.Height / 2));
float gaugeLength = (outerRectangle.Width / 2) - 2;
using (GraphicsPath path = new GraphicsPath())
{
path.AddPie(outerRectangle, GaugeStartAngle, GaugeSweepAngle);
path.AddPie(innerRectangle, GaugeStartAngle, GaugeSweepAngle);
innerRectangle.Inflate(-1, -1);
using (Pen pen = new Pen(Color.White, 3f))
using (SolidBrush backgroundbrush = new SolidBrush(canvas.BackColor))
using (LinearGradientBrush gradientBrush = new LinearGradientBrush(blendRectangle,
Color.Green, Color.Red, LinearGradientMode.ForwardDiagonal))
{
Blend blend = new Blend()
{
Factors = new[] { 0.0f, 0.0f, 0.1f, 0.3f, 0.7f, 1.0f },
Positions = new[] { 0.0f, 0.2f, 0.4f, 0.6f, 0.8f, 1.0f }
};
gradientBrush.Blend = blend;
e.Graphics.FillPath(gradientBrush, path);
e.Graphics.DrawPath(pen, path);
e.Graphics.FillEllipse(backgroundbrush, innerRectangle);
using (StringFormat format = new StringFormat())
{
format.Alignment = StringAlignment.Center;
format.LineAlignment = StringAlignment.Center;
innerRectangle.Location = new Point(innerRectangle.X, innerRectangle.Y + canvas.Font.Height);
e.Graphics.DrawString(GaugeValue.ToString() + "%", canvas.Font, Brushes.White, innerRectangle, format);
}
using (Matrix matrix = new Matrix())
{
matrix.RotateAt(GaugeStartAngle + 90 + (GaugeValue * (GaugeSweepAngle / 100)), innerCenter);
e.Graphics.Transform = matrix;
e.Graphics.DrawLine(pen, innerCenter, new PointF(innerCenter.X, innerCenter.Y - gaugeLength));
e.Graphics.ResetTransform();
}
}
}
}
private void tbarSpeed_Scroll(object sender, EventArgs e)
{
GaugeValue = tbarSpeed.Value;
Canvas.Invalidate();
}
自定义面板控件:
using System.ComponentModel;
using System.Windows.Forms;
[DesignerCategory("code")]
public class DrawingPanel : Panel
{
public DrawingPanel()
{
this.SetStyle(ControlStyles.AllPaintingInWmPaint |
ControlStyles.UserPaint |
ControlStyles.OptimizedDoubleBuffer, true);
this.UpdateStyles();
}
}
这篇关于弧形图形质量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!