Obtenir un contexte de dessin pour un WPF WriteableBitmap
Est-il possible d'obtenir un DrawingContext
(ou quelque chose de similaire)WriteableBitmap
? I. e. quelque chose pour vous permettre d'appel simple DrawLine
/DrawRectangle
/ etc méthodes, plutôt que de manipuler directement les pixels bruts.
5 réponses
j'ai trouvé la solution de sixlettervariables la plus réalisable. Cependant, il y a un "drawingContext.Close()" manquant. Selon MSDN, "un contexte de dessin doit être fermé avant que son contenu puisse être rendu". Le résultat est la fonction d'utilité 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 facilement être 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 vous n'avez pas l'esprit à l'aide de 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, comme actuellement je fais 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 le Writeablbitmap pour permettre l'accès multithread au tampon pixel, qui n'est actuellement pas autorisé avec ni un contexte de dessin ni un RenderTargetBitmap. Peut-être qu'une sorte de routine WritePixels basée sur ce que vous avez récupéré de la cible de Rendertbitmap fonctionnerait?
Il s'affiche le mot n'.
pour référence future, nous prévoyons d'utiliser un port de la Inscriptible Bitmap Extensions pour WPF.
pour une solution utilisant du code purement existant, n'importe laquelle des autres suggestions mentionnées ci-dessous fonctionnera.
Une autre façon de résoudre ce problème est d'utiliser un RenderTargetBitmap
comme un magasin de soutien, comme dans le WriteableBitmap
exemple. Ensuite, vous pouvez créer et émettre des commandes de dessin WPF à elle quand vous voulez. 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 voulez redessiner ce RenderTargetBitmap
chaque image, vous pouvez prendre le CompositionTarget.Rendering
événement, comme ceci:
CompositionTarget.Rendering += MyRenderingHandler;