Search code examples
c#wpfwriteablebitmapwriteablebitmapex

How do I write text on WriteableBitmap?


Right now I'm coding a game and I need to draw text onto a WriteableBitmap; how do I do this without converting from WritableBitmap to Bitmap to WriteableBitmap? I've searched for solutions already, but all of them slow down my game or need something like Silverlight to work.

something like this:

public class ResourceCounter : UIElement
{

    public ResourceCounter()
    {
        RenderBounds = new Bound(new Point(0, 0),
                                 new Point(600, 30));
    }

    private string goldAmt;
    private string woodAmt;
    private string stoneAmt;

    public override void Tick()
    {
        goldAmt = GlobalResources.Gold.ToString();
        woodAmt = GlobalResources.Wood.ToString();
        stoneAmt = GlobalResources.Stone.ToString();
    }

    public override void Draw(WriteableBitmap bitmap)
    {
        bitmap.FillRectangle(RenderBounds.A.X,
        Renderbounds.A.Y,
        Renderbounds.B.X,
        Renderbounds.B.Y,
        Colors.DarkSlateGray);
        bitmap.DrawString("text", other parameters...");
    }

}

Solution

  • You can share the Pixel buffer between a Bitmap and a BitmapSource

    var writeableBm1 = new WriteableBitmap(200, 100, 96, 96, 
        System.Windows.Media.PixelFormats.Bgr24, null);
    
    var w = writeableBm1.PixelWidth;
    var h = writeableBm1.PixelHeight;
    var stride = writeableBm1.BackBufferStride;
    var pixelPtr = writeableBm1.BackBuffer;
    
    // this is fast, changes to one object pixels will now be mirrored to the other 
    var bm2 = new System.Drawing.Bitmap(
        w, h, stride, System.Drawing.Imaging.PixelFormat.Format24bppRgb, pixelPtr);
    
    writeableBm1.Lock();
    
    // you might wanna use this in combination with Lock / Unlock, AddDirtyRect, Freeze
    // before you write to the shared Ptr
    using (var g = System.Drawing.Graphics.FromImage(bm2))
    {
        g.DrawString("MyText", new Font("Tahoma", 14), System.Drawing.Brushes.White, 0, 0);
    }
    
    writeableBm1.AddDirtyRect(new Int32Rect(0, 0, 200, 100));
    writeableBm1.Unlock();