Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/320.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在WPF中无缝拼接矩形,同时保持亚像素精度?_C#_Wpf_Tiles_Aliasing - Fatal编程技术网

C# 在WPF中无缝拼接矩形,同时保持亚像素精度?

C# 在WPF中无缝拼接矩形,同时保持亚像素精度?,c#,wpf,tiles,aliasing,C#,Wpf,Tiles,Aliasing,我已经在问题中描述了这个问题,但我对那里给出的答案并不满意 我画了一个条形图,画了很多彼此相邻的矩形。根据包含它们的画布的比例,由于亚像素渲染,它们之间存在可见的小间隙 我从上面的问题中学到了如何使我的矩形与屏幕像素相匹配,从而消除这种效果 不幸的是,我的图表显示的条形图可能比像素多。除了微小的间隙(表现为颜色饱和度的周期性变化)之外,这种方法效果很好。如果我用屏幕像素捕捉每个条,大多数条会消失,所以我正在寻找另一种解决方案 提前谢谢 问题原因 亚像素形状在像素内使用alpha混合。不幸的是,没

我已经在问题中描述了这个问题,但我对那里给出的答案并不满意

我画了一个条形图,画了很多彼此相邻的矩形。根据包含它们的画布的比例,由于亚像素渲染,它们之间存在可见的小间隙

我从上面的问题中学到了如何使我的矩形与屏幕像素相匹配,从而消除这种效果

不幸的是,我的图表显示的条形图可能比像素多。除了微小的间隙(表现为颜色饱和度的周期性变化)之外,这种方法效果很好。如果我用屏幕像素捕捉每个条,大多数条会消失,所以我正在寻找另一种解决方案


提前谢谢

问题原因

亚像素形状在像素内使用alpha混合。不幸的是,没有alpha混合算法可以在邻接时使矩形无缝混合

例如,如果:

  • 背景颜色为白色
  • 前景颜色为黑色,并且
  • 有两个矩形,每个矩形覆盖一个像素的一半
每个矩形将被绘制为黑色,不透明度为50%。第一个将白色像素转换为灰色。第二个将其转换为深灰色,但不是黑色。如果这些矩形在相邻像素中继续为黑色,则在黑色中会看到一个深灰色像素

两种解决方案

解决此问题的一般方法有两种:

  • 使用单个几何体定义所有矩形,或
  • 强制初始渲染具有足够高的分辨率,用户不会看到问题
  • 如何使用单个几何体

    如果只有一组矩形,则可以创建一个简单控件,使用包含组合形状的单个PathGeometry绘制整个矩形集。为了说明这个想法,如果你有两个高度不同的矩形,如下所示:

    <Rectangle Canvas.Left="0" Canvas.Top="0" Width="1.5" Height="2" Fill="Red" />
    <Rectangle Canvas.Left="1.5" Canvas.Top="0" Width="1.5" Height="4" Fill="Red" />
    
    <Path Data="M0,0 L0,2 L1.5,2 L1.5,4 L3,4 L3,0 Z" Fill="Red" />
    
    如何强制初始渲染为高分辨率

    要强制以更高分辨率渲染,请执行以下操作:

  • 在内部构建图表,使其比您想要显示的图表大几倍,例如,将其包装在视口中
  • 使用VisualBrush或RenderTargetBitmap强制单独渲染图表
  • 将用该可视化笔刷绘制的矩形添加到UI中
  • 请注意,通常情况下,当您使用ViewBrush时,WPF在以所需的实际分辨率进行渲染方面非常聪明,但如果实际图表以较大的尺寸显示在屏幕上,则可能会被欺骗,但随后会被父控件剪裁,这样您就不会看到太大的版本

    当然,RenderTargetBitmap不存在此问题,因为您指定了所需的分辨率,但知道何时重新渲染位图可能会很棘手。如果仅在数据更改时重新渲染,则可以使用事件,但如果希望任何视觉更改触发重新渲染,则更为困难

    var geo = new PathGeometry();
    var figure = new PathFigure();
    var segment = new PolyLineSegment();
    segment.Points.Add(...);
    segment.Points.Add(...);
    segment.Points.Add(...);
    segment.Points.Add(...);
    segment.Points.Add(...);
    figure.Segments.Add(segment);
    geo.Figures.Add(figure);