2014-10-01 2 views
1

Недавно я переключился на DrawingVisuals, чтобы увеличить производительность наших трендовых графиков (особенно масштабирование и панорамирование).Кэш Bitmap на DrawingVisual имеет размытые части

Вот код, у меня есть:

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 строк), но когда я включаю кеширование растрового изображения, части графика иногда размываются.

blurry lines

Кто-нибудь знает, как я могу это исправить? Я попытался изменить RenderAtScaleDrawingVisual или отключить настройку EdgeMode, но это не поможет.

EDIT: Оставьте геометрию кисти, чтобы избежать путаницы, поскольку она здесь не имеет отношения.

+0

Вы используете 'BitmapCache' (см. [Мой] (http://stackoverflow.com/q/25507861/1997232) вопрос), который выглядит как растровое изображение с использованием jpg-compession. Возможно, вы можете реализовать собственный «BitmapCache» (который не будет jpg)? Btw, чтобы иметь действительно высокопроизводительный график, мне пришлось использовать 'GDI +' в wpf. – Sinatr

+0

У вас есть пример использования GDI +, как бы я это сделал, начиная с моего примера кода? –

ответ

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 на месте (не deffered wpf рендеринга, хорошо, только блиттинг окончательного image). Вы вызываете InvalidateVisual(), чтобы перерисовать график. Обратите внимание: GC штук, они должны (особенно периодическая сборка мусора, если график часто перерисовывается).

В моем коде Figures представлен список не визуальных (простых классов, реализующих рендеринг GDI). И у вас есть визуальные дети. Это проблема, которую я оставляю для вас. Преимущество очень высокая.

+0

Раньше у меня были геометрия поверх холста, которые были перерисованы каждый раз, когда я загорался или увеличивался. Это больше похоже на это? –

+0

Нет, потому что визуальные эффекты и 'wpf' медленны. Вы устанавливаете визуальные эффекты в 'xaml'? Или, говоря иначе, представляют собой диаграммы (линии, орты, фон и т. Д.) ** должны быть визуальными? Если ответ «нет», замените их не визуальными, что только знает, как сделать себя в родительском «Graph». – Sinatr

+0

Раньше у меня были пути, а не визуальные эффекты. Эти пути имели геометрию и были добавлены на холст. –

Смежные вопросы