将 WriteableBitmap 线程化到图像控件
Posted
技术标签:
【中文标题】将 WriteableBitmap 线程化到图像控件【英文标题】:Threading WriteableBitmap to Image control 【发布时间】:2021-07-09 13:16:01 【问题描述】:我在 .NET Core 3.1 平台上使用 OpenGL 在 WPF 中呈现静态图片。上下文最初显示在隐藏的 GLFW 窗口中。然后我使用glReadPixels
读取上下文并将其显示在 UI 上的 Image 控件上,使用下面显示的代码。不使用线程时,代码工作正常。但是,当通过不同的线程调用渲染代码时,不会显示图像。作为中间检查,我创建了using (FileStream...
代码,它读取WriteableBitmap 并将其保存在本地,并且看起来工作正常;这意味着 WriteableBitmap 已正确创建。所以,我想问题是如何将 WriteableBitmap 传输到 Image 控件,这两个控件都是在不同的线程上创建的。 Dispatcher.BeginInvoke
出于某种奇怪的原因无法正常工作。
byte[] imageBuffer = new byte[imageWidth * imageHeight * 4];
glReadPixels(0, 0, imageWidth, imageHeight, GL_BGRA, GL_UNSIGNED_BYTE, imageBuffer);
imageBuffer = ImageReverse(imageBuffer, imageWidth);
PixelFormat pixelFormat = PixelFormats.Pbgra32;
int rawStride = (imageWidth * pixelFormat.BitsPerPixel) / 8;
BitmapSource bitmapSource = BitmapSource.Create(imageWidth, imageHeight, 96, 96, pixelFormat, null, imageBuffer, rawStride);
WriteableBitmap writeableBitmap = new WriteableBitmap(bitmapSource);
//This is a check whether the writeableBitmap has been created correctly
using (FileStream fileStream = new FileStream(@"C:\Temp\Image1.bmp", FileMode.Create))
BmpBitmapEncoder encoder = new BmpBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(writeableBitmap));
encoder.Save(fileStream);
Action action = new Action(() =>
_imgSoilProfile.Source = writeableBitmap;
);
_imgSoilProfile.Dispatcher.BeginInvoke(action, DispatcherPriority.Send);
【问题讨论】:
这行得通!谢谢mm8! 【参考方案1】:在设置Image
的Source
之前尝试在后台线程上调用w.Freeze()
:
using (FileStream fileStream = new FileStream(@"C:\Temp\Image1.bmp", FileMode.Create))
...
w.Freeze();
Action action = new Action(() =>
_imgSoilProfile.Source = writeableBitmap;
);
来自docs:
冻结的 Freezable 也可以跨线程共享,而未冻结的 Freezable 则不能。
【讨论】:
以上是关于将 WriteableBitmap 线程化到图像控件的主要内容,如果未能解决你的问题,请参考以下文章
在UWP 将BitmapImage转换为 WriteableBitmap