获取wpf WriteableBitmap的DrawingContext

Emp*_*LII 20 wpf drawing bitmap

有没有办法获得一个DrawingContext(或类似的)WriteableBitmap?也就是说允许你调用简单的DrawLine/ DrawRectangle/ etc类方法,而不是直接操作原始像素.

Dan*_*olf 19

我发现六个变量的解决方案是最可行的解决方案.但是,缺少"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;
}
Run Code Online (Sandbox Code Playgroud)

这可以很容易地像这样使用:

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));
    });
Run Code Online (Sandbox Code Playgroud)

  • 我的猜测是它被推崇,因为最初的问题可能类似于问"如何用这把锤子拧这个螺丝?" 答案是"使用螺丝刀"而不是如何使用锤子来做. (5认同)
  • `.Close()`隐含在`.Dispose()`中 - 这是`using`语句背后的全部内容.如果你在使用块中留下*only*`render(...)`命令,你会没事的,也不需要任何`.Close()`. (4认同)
  • 在这个答案中没有`WriteableBitmap`,为什么它是最顶层的?:)这与问题完全无关. (4认同)

Dan*_*bić 16

如果您不介意使用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();                    
Run Code Online (Sandbox Code Playgroud)

  • 为了防止有人想知道,我测试了本主题中提到的DrawingVisual WPF方法和这个System.Drawing方法,这个System.Drawing方法非常快.我对WPF非常失望. (2认同)

use*_*116 5

我想知道同样的事情,因为目前我做的事情如下:

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;
}
Run Code Online (Sandbox Code Playgroud)

我正在尝试使用WriteableBitmap来允许对像素缓冲区进行多线程访问,目前不允许使用DrawingContext和RenderTargetBitmap.也许根据你从RenderTargetBitmap中检索到的某些WritePixels例程可以工作吗?


Emp*_*LII 4

看来这个词是 no


为了将来的参考,我们计划使用WPF 的可写位图扩展的端口。

对于使用纯粹现有代码的解决方案,下面提到的任何其他建议都可以。