获取WPF WriteableBitmap的DrawingContext
时间:2020-03-06 14:19:19 来源:igfitidea点击:
有没有办法为WriteableBitmap
获得DrawingContext
(或者类似的东西)? IE。可以让我们调用简单的DrawLine
/DrawRectangle
/ etc等方法,而不是直接操作原始像素。
解决方案
我想知道同一件事,因为目前我正在做类似的事情:
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当前均不允许这样做。基于我们从RenderTargetBitmap检索的内容的某种WritePixels例程可能行得通吗?
看来这个词是"否"。
为了将来参考,我们计划使用WPF的Writeable Bitmap Extensions的端口。
对于使用纯现有代码的解决方案,下面提到的任何其他建议都可以使用。
如果我们不介意使用" 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();
我发现sixlettervariables解决方案是最可行的解决方案。但是,缺少" 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)); });