我编写的应用程序显示我从某个网络层获取的图像。 我将图像作为字节数组获取,然后进行反序列化并将 byte[] 转换为位图图像并将其显示在我的 wpf 应用程序中。
图像每 50 毫秒更改一次。
我正在考虑一种有效的方法 - 我如何使用最少的 GC 调用...
我的意思是 .. 当我需要创建新的位图图像时,我该如何处理旧的位图图像?
旧的 bitmapImage 是否有任何重用或类似的东西,并通过这种方式减少对 GC 的调用次数?
最佳答案
您需要避免在每一帧都创建新的字节数组。您可以使用 Array.Copy(或 C# 指针)将数据从网络服务复制到图像源。
但是,如果您的网络服务消耗太多内存,因为它会为每个帧创建新的字节数组,那么您就会遇到问题。
我已将相机实时流添加到我的 WPF 应用程序并注意到一个有趣的事实。我正在使用 EgmuCV 抓取帧。它给我捕获的帧作为 System.Drawing.Bitmap
。我正在使用转换器将帧转换为 BitmapImage
。性能相当不错。
有趣的是,当我调用 bitmap.Save(filePath)
或 bitmap.Copy()
时,它会保存流中的最新帧,而不是创建位图时的帧。当我在同一个位图实例上多次调用保存时,我得到了不同的图像。这意味着位图下的数据一直在变化,而不是一直在创建新数据,而这正是您应该实现的。这是代码:
_grabber = new Capture();
....
//on frame requested:
Image<Brg, byte> currentFrame = _grabber.QueryFrame();
Bitmap bitmap = currentFrame.Bitmap; //System.Drawing
public class BitmapToImageSourceConverter: IValueConverter
{
[HandleProcessCorruptedStateExceptions]
[SecurityCritical]
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value == null) return null;
var bitmap = (Bitmap) value;
var hBitmap = bitmap.GetHbitmap();
using (var handle = new SafeHBitmapHandle(hBitmap, true))
{
if (handle.IsInvalid) return null;
return System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
handle.DangerousGetHandle(),
IntPtr.Zero,
Int32Rect.Empty,
BitmapSizeOptions.FromEmptyOptions());
}
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
关于c# - 如何在 WPF 上有效替换高频图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31260410/