C# 将非托管位图绘制到屏幕的正确方法

C# 将非托管位图绘制到屏幕的正确方法,c#,xaml,user-interface,bitmap,uwp,C#,Xaml,User Interface,Bitmap,Uwp,我正忙着创建一个xaml视图,用于将位图从非托管代码绘制到屏幕上-使用画布背景画笔。有几件事我不确定(尤其是因为文档很少/缺失) 我正在使用SkiaSharep进行绘图,因此必须在非托管内存中访问内存块,并且我希望避免来回复制 我已经找到了一些方法来做到这一点,但我不确定框架的工作原理,不知道我是否做到了这一点。第一种方法是使用字节[]和可写位图: int width, height, length = ...; // create the bits (once off) byte[] pix

我正忙着创建一个xaml视图,用于将位图从非托管代码绘制到屏幕上-使用
画布
背景
画笔
。有几件事我不确定(尤其是因为文档很少/缺失)

我正在使用SkiaSharep进行绘图,因此必须在非托管内存中访问内存块,并且我希望避免来回复制

我已经找到了一些方法来做到这一点,但我不确定框架的工作原理,不知道我是否做到了这一点。第一种方法是使用
字节[]
可写位图

int width, height, length = ...;

// create the bits (once off)
byte[] pixels = new byte[length];
GCHandle buff = GCHandle.Alloc(pixels, GCHandleType.Pinned);
WriteableBitmap bitmap = new WriteableBitmap(width, height);
this.Background = new ImageBrush { ImageSource = bitmap };

// draw (in a game loop)
DrawUsingSkiaSharp(buff.AddrOfPinnedObject());

// update the UI
var stream = bitmap.PixelBuffer.AsStream();
stream.Seek(0, SeekOrigin.Begin);
stream.Write(pixels, 0, pixels.Length);
bitmap.Invalidate();
这工作很好,我只复制“一次”每帧。此外,我可以绘制相同的图像,位图充当双缓冲区。但是,
位图.Invalidate
是否会导致第二次复制到屏幕上

我发现我也可以使用
软件位图

// create
SoftwareBitmap bitmap = new SoftwareBitmap(
    BitmapPixelFormat.Bgra8, 
    width, height, 
    BitmapAlphaMode.Premultiplied);

// draw
using (var buffer = bitmap.LockBuffer(BitmapBufferAccessMode.ReadWrite))
using (var bufferRef = buffer.CreateReference())
{
    byte* b;
    uint capacity;
    ((IMemoryBufferByteAccess)bufferRef).GetBuffer(out b, out capacity);
    DrawUsingSkiaSharp(b);
}

// update
var source = new SoftwareBitmapSource();
this.Background = new ImageBrush { };
var action = source.SetBitmapAsync(bitmap);
action.Completed = (asyncInfo, asyncStatus) {
    ((ImageBrush)this.Background).ImageSource = source;
};
但是一旦我将位图分配给画笔,我就不能再在上面画画了(LockBuffer抛出)。解决这个问题的一种方法是使用第二个位图并复制到该位图。但是,这是不是比
可写位图
有所改进,尤其是我现在必须处理异步复杂性?
SetBitmapAsync
真正做什么?为什么是异步的?消息来源难道不能直接读出来吗?或者这里也有副本吗

是否有第三种更好的方法,我应该使用其中一种还是另一种,或者有不同的方法来做到这一点?比如不使用画笔直接在
画布上绘制(或者有更好的控件)

另外,在使用游戏循环绘图时,使用
SoftwareBitmap
SoftwareBitmapSource
的正确方法是什么


这么多选项,而且没有文档!:)

尽管这个nuget包缺少文档,但是您仍然可以对一些问题进行研究,例如,为什么一个方法是异步的,尝试用谷歌搜索它。您是否已经检查了
SkiaSharp
的示例?你开发了uwp应用程序吗?由于您的问题太多,而且没有中心主题,因此可能需要花费更多的时间来回复您。尽管此nuget软件包缺少文档,但您仍然可以对一些问题进行研究,例如,为什么一个方法是异步的,请尝试用谷歌搜索它。您是否已经检查了
SkiaSharp
的示例?你开发了uwp应用程序吗?因为你的问题太多,没有一个中心话题,所以它可能会花更多的时间来回答你。