Question

Est-il possible d'obtenir un DrawingContext (ou quelque chose de similaire) pour un WriteableBitmap ? C'est à dire. pour vous permettre d'appeler des méthodes simples DrawLine / DrawRectangle / etc, plutôt que de manipuler directement les pixels bruts.

Était-ce utile?

La solution 4

Il semble que le mot est non .

Pour référence ultérieure, nous prévoyons d’utiliser un port des extensions de script enregistrables pour WPF.

Pour une solution utilisant du code purement existant, l'une des autres suggestions mentionnées ci-dessous fonctionnera.

Autres conseils

J'ai trouvé la solution de sixlettervariables la plus pratique. Cependant, il existe un "drawingContext.Close ()". disparu. Selon MSDN, "Un DrawingContext doit être fermé pour que son contenu puisse être rendu". Le résultat est la fonction utilitaire suivante:

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

Ceci peut alors être facilement utilisé comme ceci:

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

Si cela ne vous dérange pas d'utiliser System.Drawing vous pourriez faire quelque chose comme:

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

Je me demande la même chose, car je fais actuellement quelque chose comme:

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

J'essaie d'utiliser WriteableBitmap pour permettre un accès multithread au tampon de pixels, ce qui n'est actuellement pas autorisé avec un DrawingContext ni un RenderTargetBitmap. Peut-être qu'une sorte de routine WritePixels basée sur ce que vous avez récupéré à partir de RenderTargetBitmap fonctionnerait?

Une autre façon de résoudre ce problème consiste à utiliser un RenderTargetBitmap en tant que magasin de sauvegarde, comme dans l'exemple WriteableBitmap . Vous pouvez ensuite créer et émettre des commandes de dessin WPF quand vous le souhaitez. Par exemple:

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

Si vous souhaitez redessiner ce RenderTargetBitmap à chaque image, vous pouvez intercepter l'événement CompositionTarget.Rendering , comme ceci:

CompositionTarget.Rendering += MyRenderingHandler;
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top