最近我切换到DrawingVisuals
以提高趋势图的效果(尤其是缩放和平移)。
这是我的代码:
blocksToBeRendered = (baseItem as AvgCurve).GetStreamGeometryBlocks(ActualWidth, ActualHeight, _minPoint.X, _maxPoint.X, FixTimeStep ? _timeStep : 0, IsMainChart);
Pen stroke = new Pen((baseItem as AvgCurve).LineBrush, 1);
foreach (GeometryGroup group in blocksToBeRendered)
{
if (group.Children.Count != 0)
{
if (!cachedBlocks[baseItem].Any(x => x.Children[0] == group.Children[0]))
{
cachedBlocks[baseItem].Add(group);
ImprovedDrawingVisual vis = new ImprovedDrawingVisual();
BitmapCache cache = new BitmapCache() { SnapsToDevicePixels = true };
vis.CacheMode = cache;
using (DrawingContext context = vis.RenderOpen())
{
RenderOptions.SetEdgeMode(group, EdgeMode.Aliased);
if (group.Children.Count > 0)
{
context.DrawGeometry(null, stroke, group.Children[0]);
}
}
_host.VisualCollection.Add(vis);
}
}
}
这是ImprovedDrawingVisual
:
public class ImprovedDrawingVisual: DrawingVisual
{
public ImprovedDrawingVisual()
{
VisualEdgeMode = EdgeMode.Aliased;
VisualBitmapScalingMode = BitmapScalingMode.NearestNeighbor;
}
}
现在,几何体确实有Transforms
,这可能很重要。
图形很好地绘制而没有位图缓存(1 px行),但是当我打开位图缓存时,图形的某些部分有时会变得模糊。
有谁知道如何解决这个问题?我尝试更改RenderAtScale
的{{1}}或关闭DrawingVisual
设置,但这没有帮助。
编辑:省略画笔填充几何图形以避免混淆,因为它与此处无关。
答案 0 :(得分:1)
如果您决定在GDI+
中尝试wpf
,那么绘图将如下所示:
using GDI = System.Drawing;
private int _counter; // count redraws
protected override void OnRender(DrawingContext context)
{
if (Figures != null && RenderSize.Height > 0 && RenderSize.Width > 0)
using (var bitmap = new GDI.Bitmap((int)RenderSize.Width, (int)RenderSize.Height))
{
using (var graphics = GDI.Graphics.FromImage(bitmap))
foreach (var figure in Figures)
figure.Render(this, graphics);
// draw image
var hbitmap = bitmap.GetHbitmap();
var size = bitmap.Width * bitmap.Height * 4;
GC.AddMemoryPressure(size);
var image = Imaging.CreateBitmapSourceFromHBitmap(hbitmap, IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
image.Freeze();
context.DrawImage(image, new Rect(RenderSize));
DeleteObject(hbitmap);
GC.RemoveMemoryPressure(size);
// trigger garbage collecting
if (_counter++ > 10)
GC.Collect(3);
}
}
这基本上会渲染Graph
(没有默认的wpf
渲染,只有最终image
的blitting。您调用InvalidateVisual()
重绘图表。注意GC
个问题,它们是必须的(特别是如果图形经常被重新绘制,则定期进行垃圾收集)。
在我的代码中Figures
是一个非可视化列表(简单类,也实现了GDI渲染)。你有视觉孩子。这是问题,我留给你解决。好处是非常高的性能。