将 WriteableBitmap 线程化到 Image 控件
Threading WriteableBitmap to Image control
我在 .NET Core 3.1 平台上使用 OpenGL 在 WPF 中渲染静态图片。上下文最初显示在隐藏的 GLFW window 中。然后我使用 glReadPixels
读取上下文并将其显示在 UI 上的图像控件上,代码如下所示。不使用线程时,代码工作正常。但是,当通过不同的线程调用渲染代码时,图像不会显示。作为中间检查,我创建了 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);
在设置 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:
A frozen Freezable can also be shared across threads, while an unfrozen Freezable cannot.
我在 .NET Core 3.1 平台上使用 OpenGL 在 WPF 中渲染静态图片。上下文最初显示在隐藏的 GLFW window 中。然后我使用 glReadPixels
读取上下文并将其显示在 UI 上的图像控件上,代码如下所示。不使用线程时,代码工作正常。但是,当通过不同的线程调用渲染代码时,图像不会显示。作为中间检查,我创建了 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);
在设置 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:
A frozen Freezable can also be shared across threads, while an unfrozen Freezable cannot.