Quantcast
Channel: WriteableBitmapEx
Viewing all articles
Browse latest Browse all 360

New Post: How to draw text in WPF without WriteableBitmap constructor that takes UIElement parameter?

$
0
0
Thanks for the quick response. It works using this approach, then blitting with my base WriteableBitmap.

On performance, I'm seeing ~600uS to create each label and cache it in a WriteableBitmap object. For my use case of ~100K items (1 item = rectangle and label), the time to create each and cache for subsequent blitting would be >55s which is too much. Is this the most performant text approach that I should expect? Would the Silverlight UIElement conversion take about the same time? Maybe this is just my wake up call that drawing text is expensive.

As for the blitting of a cached text bitmap into the base, the performance is quite reasonable averaging 720nS per-blit; thus 72ms for my 100K case, although I plan to only conditionally add the text if determined it will be readable.

Benchmark system: Core i7 Q740, 1.73Ghz, 8GB RAM, W7 x64

//-----------------------------------

To summarize my approach for others, given the performance seen:
  1. Create a WriteableBitmap for the text (created on-demand and cached for future repeated use)
    a) DrawingVisual's DrawingContext.DrawText (<FormattedText>, new Point(0,0))
    b) Use the bounds of the FormattedText object as the 'sourceRect'
    c) Convert the DrawingVisual to a RenderTargetBitmap using sourceRect from (b)
    d) Create a WriteableBitmap object dimensioned the same size as sourceRect
            FormattedText text = new FormattedText(displayLabel,
                new System.Globalization.CultureInfo("en-us"),
                FlowDirection.LeftToRight,
                new Typeface(new FontFamily("Arial"), FontStyles.Normal, FontWeights.Normal, new FontStretch()),
                12,
                Brushes.Black);

            DrawingVisual drawingVisual = new DrawingVisual();
            DrawingContext drawingContext = drawingVisual.RenderOpen();
            drawingContext.DrawText(text, new Point(0, 0));
            drawingContext.Close();


            Rect sourceRect = new Rect(0, 0, (int)text.Width, (int)text.Height);

            RenderTargetBitmap rtb = new RenderTargetBitmap((int)sourceRect.Width, (int)sourceRect.Height, 96, 96, PixelFormats.Pbgra32);
            rtb.Render(drawingVisual);

            LabelBitmapCache = BitmapFactory.New((int)sourceRect.Width, (int)sourceRect.Height);
            rtb.CopyPixels(new Int32Rect(0, 0, rtb.PixelWidth, rtb.PixelHeight), 
                            LabelBitmapCache.BackBuffer, 
                            LabelBitmapCache.BackBufferStride * LabelBitmapCache.PixelHeight, 
                            LabelBitmapCache.BackBufferStride);
  1. Conditionally blit the text cached WriteableBitmap with my base (if determined it will be readable - not shown)
_bmp.Blit(new Rect(left, 5, i.LabelBitmapCache.PixelWidth, i.LabelBitmapCache.PixelHeight), i.LabelBitmapCache, 
                                  new Rect(0,0,i.LabelVisual.ContentBounds.Width, i.LabelVisual.ContentBounds.Height));

Viewing all articles
Browse latest Browse all 360

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>