我遇到问题Tiling rectangles seamlessly in WPF中描述的问题,但我对那里给出的答案并不满意。
我正在绘制一个条形图,通过绘制彼此相邻的许多矩形。根据包含它们的画布的比例,由于子像素渲染,其中一些画面之间可见小间隙。
我从上面的问题中了解到如何使我的矩形与屏幕像素相符,从而消除了这种影响。
不幸的是,我的图表可能会显示比像素更多的条形图。除了微小的间隙(表现为颜色饱和度的周期性变化)之外,这种方法效果很好。如果我用屏幕像素捕捉每个条形图,大多数条形图都消失了,所以我正在寻找另一个解决方案。
提前致谢!
答案 0 :(得分:2)
问题原因
子像素形状在像素内使用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" />
您可以使用单个PathGeometry渲染它,如下所示:
<Path Data="M0,0 L0,2 L1.5,2 L1.5,4 L3,4 L3,0 Z" Fill="Red" />
实现这一目标的一种实用方法是:
Data
属性绑定到数据源。如果您使用布局系统来定位矩形,您可能希望通过为每个矩形创建一个Adorner来使用AdornerLayer,然后在渲染装饰时计算第一个矩形的组合路径并使其余部分不可见。
以上假设很容易从源数据生成PathGeometry。对于更复杂的场景,Path控件可以被子类化以搜索其父级的可视树以获取指定的形状,并使用通用的几何算法来计算表示它们的并集而没有额外边缘的PathGeometry。
如果你的矩形有多种颜色,你可以使用每种颜色一个多个Path控件,或者你可以构造一个Drawing对象并显示它。
以下是构造PathGeometry的代码结构:
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);
如何强制初始渲染为高分辨率
强制以更高分辨率渲染:
请注意,通常WPF在使用ViewBrush时以实际分辨率渲染是很聪明的,但是实际图表实际显示在屏幕上的较大尺寸可能会被欺骗,但是后来被父控件剪切了所以你实际上并没有看到太大的版本。
当然,RenderTargetBitmap不存在此问题,因为您指定了所需的分辨率,但知道何时重新渲染位图可能会非常棘手。如果您只对数据更改进行重新渲染,则可以使用事件,但如果您希望任何可视更改触发重新渲染,则会更加困难。
答案 1 :(得分:1)
Target 4.0, use layout rounding(带演示的博文)。