Frage

Gibt es eine Möglichkeit, ein DrawingContext (oder so ähnlich) für eine WriteableBitmap zu bekommen? D. h etwas, damit Sie einfach DrawLine / DrawRectangle / etc Arten von Methoden nennen, anstatt zu manipulieren die rohen Pixel direkt.

War es hilfreich?

Lösung 4

Es erscheint das Wort ist nicht .


Für die Zukunft planen wir, einen Port des Beschreibbare Bitmap-Erweiterungen für WPF.

Für eine Lösung rein bestehenden Code, alle anderen Vorschläge unten erwähnt wird funktionieren.

Andere Tipps

fand ich sixlettervariables' Lösung der machbaren. Allerdings gibt es eine „drawingContext.Close ()“ fehlt. Laut MSDN, „A DrawingContext muss geschlossen werden, bevor sein Inhalt gemacht werden kann“. Das Ergebnis ist die folgende Nutzenfunktion:

public static BitmapSource CreateBitmap(
    int width, int height, double dpi, Action<DrawingContext> render)
{
    DrawingVisual drawingVisual = new DrawingVisual();
    using (DrawingContext drawingContext = drawingVisual.RenderOpen())
    {
        render(drawingContext);
    }
    RenderTargetBitmap bitmap = new RenderTargetBitmap(
        width, height, dpi, dpi, PixelFormats.Default);
    bitmap.Render(drawingVisual);

    return bitmap;
}

Dies kann dann leicht wie folgt verwendet werden:

BitmapSource image = ImageTools.CreateBitmap(
    320, 240, 96,
    drawingContext =>
    {
        drawingContext.DrawRectangle(
            Brushes.Green, null, new Rect(50, 50, 200, 100));
        drawingContext.DrawLine(
            new Pen(Brushes.White, 2), new Point(0, 0), new Point(320, 240));
    });

Wenn Sie nicht mit nichts dagegen System.Drawing könnten Sie so etwas wie:

var wb = new WriteableBitmap( width, height, dpi, dpi, 
                              PixelFormats.Pbgra32, null );
wb.Lock();
var bmp = new System.Drawing.Bitmap( wb.PixelWidth, wb.PixelHeight,
                                     wb.BackBufferStride, 
                                     PixelFormat.Format32bppPArgb, 
                                     wb.BackBuffer );

Graphics g = System.Drawing.Graphics.FromImage( bmp ); // Good old Graphics

g.DrawLine( ... ); // etc...

// ...and finally:
g.Dispose(); 
bmp.Dispose();
wb.AddDirtyRect( ... );
wb.Unlock();                    

Ich bin das Gleiche fragen, wie ich derzeit so etwas wie:

DrawingVisual drawingVisual = new DrawingVisual();
using (DrawingContext drawingContext = drawingVisual.RenderOpen())
{
   //
   // ... draw on the drawingContext
   //
   RenderTargetBitmap bmp = new RenderTargetBitmap(width, height, dpi, dpi, PixelFormats.Default);
   bmp.Render(drawingVisual);
   image.Source = bmp;
}

Ich versuche, die Writeablebitmap zu verwenden multithreaded Zugriff auf die Pixelpuffer zu ermöglichen, die derzeit nicht mit weder einem DrawingContext erlaubt noch eine Rendertargetbitmap. Vielleicht Routine eine Art WritePixels basiert weg von dem, was man aus dem Rendertargetbitmap abgerufen haben würde funktionieren?

Eine andere Möglichkeit, dieses Problem zu lösen, ist einen RenderTargetBitmap als Hintergrundspeicher zu verwenden, wie in dem WriteableBitmap Beispiel. Dann können Sie erstellen und Ausgabe WPF Zeichenbefehle, um es, wann immer Sie wollen. Zum Beispiel:

// create the backing store in a constructor
var backingStore = 
      new RenderTargetBitmap(200,200,97,97,PixelFormats.Pbgra32);
myImage.Source = backingStore;

// whenever you want to update the bitmap, do:
var drawingVisual = new DrawingVisual();
var drawingContext = drawingVisual.RenderOpen();
{
    // your drawing commands go here
    drawingContext.DrawRectangle(
            Brushes.Red, new Pen(),
            new Rect(this.RenderSize));
}
Render(drawingContext);
drawingContext.Close();
backingStore.Render(drawingVisual);

Wenn Sie diese RenderTargetBitmap jeden Frame neu zu zeichnen wollen, können Sie das CompositionTarget.Rendering Ereignis fangen, wie folgt aus:

CompositionTarget.Rendering += MyRenderingHandler;
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top