C# 将非托管位图绘制到屏幕的正确方法
我正忙着创建一个xaml视图,用于将位图从非托管代码绘制到屏幕上-使用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
画布
背景画笔
。有几件事我不确定(尤其是因为文档很少/缺失)
我正在使用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应用程序吗?因为你的问题太多,没有一个中心话题,所以它可能会花更多的时间来回答你。