Получение DrawingContext для wpf WriteableBitmap - PullRequest
20 голосов
/ 18 сентября 2008

Есть ли способ получить DrawingContext (или что-то подобное) для WriteableBitmap? То есть что-то, что позволит вам вызывать простые DrawLine / DrawRectangle / etc методы, а не напрямую управлять необработанными пикселями.

Ответы [ 5 ]

19 голосов
/ 15 мая 2009

Я нашел решение с шестью переменными наиболее подходящим. Тем не менее, отсутствует «DrawingContext.Close ()». Согласно MSDN, «DrawingContext должен быть закрыт, прежде чем его содержимое может быть отображено». В результате получается следующая служебная функция:

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

Это можно легко использовать следующим образом:

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));
    });
16 голосов
/ 28 апреля 2009

Если вы не возражаете против использования System.Drawing, вы можете сделать что-то вроде:

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();                    
5 голосов
/ 18 сентября 2008

Мне интересно то же самое, что и сейчас я делаю что-то вроде:

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

Я пытаюсь использовать WriteableBitmap, чтобы разрешить многопоточный доступ к пиксельному буферу, который в настоящее время не разрешен ни для DrawingContext, ни для RenderTargetBitmap. Может быть, какая-то подпрограмма WritePixels, основанная на том, что вы извлекли из RenderTargetBitmap, сработает?

4 голосов
/ 23 сентября 2008

Появляется слово не .


Для дальнейшего использования мы планируем использовать порт Расширяемые записи растрового изображения для WPF.

Для решения, использующего чисто существующий код, подойдут любые другие предложения, упомянутые ниже.

1 голос
/ 08 июня 2017

Другой способ решения этой проблемы - использовать RenderTargetBitmap в качестве резервного хранилища, как в примере WriteableBitmap. Затем вы можете создавать и выдавать ему команды рисования WPF в любое время. Например:

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

Если вы хотите перерисовать этот RenderTargetBitmap каждый кадр, вы можете перехватить событие CompositionTarget.Rendering, например:

CompositionTarget.Rendering += MyRenderingHandler;
...