gpt4 book ai didi

c# - 如何避免带有圆角的可缩放用户控件的彩色边框的视觉伪影?

转载 作者:行者123 更新时间:2023-11-30 22:56:00 25 4
gpt4 key购买 nike

我有一个 Form,其中包含:

  1. 一个TrackBar(最小=1,最大=200,代表缩放百分比);
  2. UserControlBorderStyle = BorderStyle.None

相关代码

表格1

来自设计器代码

trackBar1.Value = 100;
BackColor = Color.Gray;

来自代码隐藏

private void trackBar1_Scroll(object sender, EventArgs e)
{
userControl11.SetZoomFactor(trackBar1.Value / 100F);
}

用户控件1

internal float MyBaseWidth;

public UserControl1()
{
InitializeComponent();

MyBaseWidth = Width;

SetZoomFactor(1);
}

protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);

e.Graphics.SmoothingMode = SmoothingMode.HighQuality;
e.Graphics.CompositingQuality = CompositingQuality.HighQuality;
e.Graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;

Pen p = new Pen(Color.Yellow);
e.Graphics.DrawPath(p, GraphicsPathWithBorder);
}

internal GraphicsPath GraphicsPathWithBorder;

internal void SetZoomFactor(float z)
{
Width = (int)(MyBaseWidth * z);

GraphicsPathWithBorder = RoundedCornerRectangle(ClientRectangle);
Region = new Region(GraphicsPathWithBorder);
}

internal static GraphicsPath RoundedCornerRectangle(Rectangle r)
{
GraphicsPath path = new GraphicsPath();
float size = 10 * 2F;

path.StartFigure();

path.AddArc(r.X, r.Y,
size, size, 180, 90);
path.AddArc((r.X + (r.Width - size)), r.Y,
size, size, 270, 90);
path.AddArc((r.X + (r.Width - size)), (r.Y + (r.Height - size)),
size, size, 0, 90);
path.AddArc(r.X, (r.Y + (r.Height - size)),
size, size, 90, 90);

path.CloseFigure();

return path;
}

初始截图

initially

使用轨迹栏后的截图

after zoom

右边黄色边框缩小后不可见,放大时右边有多个黄色边框。

更新:

答案有效,但有一部分控件超出了边界。 curveSize = 20 右上角的屏幕截图:

curve 1

对于 curveSize = 24:

curve 2

最佳答案

我建议使用一种稍微不同的方法来绘制边框和用户控件的内容,该方法还应该解决重绘控件时生成的伪像。

当您为控件创建一个区域,然后按原样绘制该区域时,绘制的外边界未消除锯齿:锯齿像素落在该区域之外。当在区域边界周围绘制边框时,当然会应用相同的效果。

在这里,我申请了一个 Scale Matrix和一个 Translate Matrix 缩放和移动定义控件边界的外部区域内部的区域边界。
缩放和平移变换的大小由 Pen 大小决定。
有关 Matrix 用法的更多信息,请参见:Flip the GraphicsPath

在这种情况下,绘制边框时,边框的外部抗锯齿部分位于区域边界内,抗锯齿效果得以保留。
控件的背景颜色设置为 Color.Transparent(用户控件本身支持颜色透明度)。

我还添加了几个(非修饰的)属性,允许定义内部颜色(控件的 BackColor)以及边框的大小和颜色。其余部分与之前大致相同。

示例结果:

Rounded Zoomable UserControl


using System.Drawing;
using System.Drawing.Drawing2D;

public partial class RoundControl : UserControl
{
private GraphicsPath GraphicsPathWithBorder;
private float MyBaseWidth;
private float m_PenSize = 2f;
private Color m_BorderColor = Color.Yellow;
private Color m_FillColor = Color.Green;

public RoundControl()
{
ResizeRedraw = true;
InitializeComponent();
MyBaseWidth = Width;
}

public float BorderSize
{
get => m_PenSize;
set {
m_PenSize = value;
Invalidate();
}
}

public Color BorderColor
{
get => m_BorderColor;
set {
m_BorderColor = value;
Invalidate();
}
}

public Color FillColor
{
get => m_FillColor;
set {
m_FillColor = value;
Invalidate();
}
}

protected override void OnLayout(LayoutEventArgs e) {
UpdateRegion();
base.OnLayout(e);
}

protected override void OnPaint(PaintEventArgs e)
{
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
RectangleF rect = GraphicsPathWithBorder.GetBounds();
float scaleX = 1 - ((m_PenSize + 1) / rect.Width);
float scaleY = 1 - ((m_PenSize + 1) / rect.Height);
using (Pen pen = new Pen(m_BorderColor, m_PenSize))
using (Brush brush = new SolidBrush(m_FillColor))
using (Matrix mx = new Matrix(scaleX, 0, 0, scaleY, pen.Width / 2, pen.Width / 2))
{
e.Graphics.Transform = mx;
e.Graphics.FillPath(brush, GraphicsPathWithBorder);
e.Graphics.DrawPath(pen, GraphicsPathWithBorder);
}
base.OnPaint(e);
}

internal void SetZoomFactor(float z) {
int newWidth = (int)(MyBaseWidth * z);
if (newWidth <= (30 + m_PenSize * 2)) return;
Width = newWidth;
UpdateRegion();
}


private void UpdateRegion() {
GraphicsPathWithBorder = RoundedCornerRectangle(ClientRectangle);
Region = new Region(GraphicsPathWithBorder);
Invalidate();
}

private GraphicsPath RoundedCornerRectangle(Rectangle r)
{
GraphicsPath path = new GraphicsPath();
// Fixed curve size since we only scale on X-dimension
// Otherwise, adjust also considering the height
float curveSize = 10 * 2.4F;

path.StartFigure();
path.AddArc(r.X, r.Y, curveSize, curveSize, 180, 90);
path.AddArc(r.Right - curveSize, r.Y, curveSize, curveSize, 270, 90);
path.AddArc(r.Right - curveSize, r.Bottom - curveSize, curveSize, curveSize, 0, 90);
path.AddArc(r.X, r.Bottom - curveSize, curveSize, curveSize, 90, 90);
path.CloseFigure();
return path;
}
}

关于c# - 如何避免带有圆角的可缩放用户控件的彩色边框的视觉伪影?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54787704/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com