Pregunta

Es allí una manera de conseguir un DrawingContext (o algo similar) para un WriteableBitmap?I. e.algo que le permiten llamar a simple DrawLine/DrawRectangle/etc tipo de métodos, en lugar de manipular los píxeles crudos directamente.

¿Fue útil?

Solución 4

Parece la palabra no es.


Para referencia en el futuro, tenemos la intención de utilizar un puerto de la Escritura De Mapa De Bits Extensiones para WPF.

Para una solución de uso puramente código existente, cualquiera de las otras sugerencias que se mencionan a continuación va a trabajar.

Otros consejos

He encontrado sixlettervariables' solución más viables uno.Sin embargo, hay un "drawingContext.Close()" que falta.De acuerdo a MSDN, "UN DrawingContext debe estar cerrada antes de que su contenido puede ser interpretada".El resultado es el siguiente función de utilidad:

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

Esto puede ser fácilmente utilizado como esta:

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 no te importa usar System.Drawing se podría hacer algo como:

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

Me pregunto lo mismo, ya que actualmente tengo que hacer algo como:

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

Estoy tratando de utilizar el WriteableBitmap para permitir el acceso multiproceso para el pixel buffer, que es en la actualidad no se permite ni un DrawingContext ni un RenderTargetBitmap.Tal vez algún tipo de WritePixels una rutina basada en lo que has recuperado de la RenderTargetBitmap iba a funcionar?

Una manera diferente de resolver este problema es el uso de un RenderTargetBitmap como una copia de seguridad de la tienda, al igual que en el WriteableBitmap ejemplo.A continuación, puede crear y emitir WPF comandos de dibujo siempre que lo desee.Por ejemplo:

// 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 desea volver a dibujar esto RenderTargetBitmap cada fotograma, se puede coger el CompositionTarget.Rendering evento, como este:

CompositionTarget.Rendering += MyRenderingHandler;
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top