本文介绍了在DrawingVisual位图缓存有模糊的地方的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

最近,我切换到 DrawingVisuals 来增加我们的趋势图(尤其是缩放和平移)的性能。

Recently I switched to DrawingVisuals to increase the performance of our trending graphs (especially zooming and panning).

这里的code我有:

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;
    }
}

现在,几何体确实有变换,这可能是非常重要的。

Now, the geometries do have Transforms, which might be important.

什么情况是,图形是很好绘制没有位图缓存(1像素线),但是当我打开位图缓存,图形部分地区有时去模糊全部

What happens is that the graphs are drawn nicely without bitmap caching (1 px lines), but when I turn on bitmap caching, parts of the graph go all blurry sometimes.

有谁知道我怎么能解决这个问题?我试图改变 RenderAtScale DrawingVisual 或关闭 EdgeMode 设置,但这并不能帮助。

Does anyone know how I can fix this? I tried changing the RenderAtScale of the DrawingVisual or turning off the EdgeMode setting, but that doesn't help.

编辑:左刷出填补几何,以避免混淆,因为它不是与此有关。

Left out the brush fill geometry to avoid confusion since it's not relevant here.

推荐答案

如果你决定尝试 GDI + WPF ,然后绘图将是这样的:

If you decide to try GDI+ in wpf, then drawing will looks like this:

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);
      }
}

这基本上使到位(不递延 WPF 渲染,好了,只有块传输的最后图片)。你叫 InvalidateVisual()重新绘制图表。通知 GC 一样的东西,他们必须(尤其是周期性的垃圾收集,如果图表被重绘频繁)。

This basically renders Graph in place (no deffered wpf rendering, well, only blitting of final image). You call InvalidateVisual() to redraw graph. Notice GC thingies, they are must (especially periodic garbage collection if graph gets redrawn frequently).

在我的code 非视觉效果(简单的类,实施GDI渲染为好)的列表。你有视觉的孩子。这是问题,这是我离开你解决。这样做的好处是非常高的性能。

In my code Figures is a list of non-visuals (simple classes, implementing GDI rendering as well). And you have visual children. It's the problem, which I leave for you to solve. The benefit is very high performance.

这篇关于在DrawingVisual位图缓存有模糊的地方的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-02 05:09