制作不断更新的图像(WPF)

时间:2014-08-26 18:07:33

标签: c# wpf bitmap

所以我正在搞乱制作一个简单的AI和基本的C#,在这个项目中,我有很多点,我通过制作位图可视化。 这个位图我已经渲染/加载到WPF窗口中的一个图像对象..但我的问题是每个毫秒渲染,使得帧率非常差 - 所以我怎样才能做得更好?

我可以“不断”加载吗?或者我应该采取另一种方法?

我现在得到的非常简单,但无论如何我都可以展示重要的部分,从全班中取出:

private static Bitmap BitMap = new Bitmap(500, 500);

static Graphics GraphicFromBitMap
{
    get
    {
        return Graphics.FromImage(BitMap);
    }
}

public static BitmapSource loadBitmapAsImage()
{
    IntPtr intPtr = BitMap.GetHbitmap();
    BitmapSource bitmapSource = null;
    try
    {
        bitmapSource = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(intPtr,
        IntPtr.Zero, Int32Rect.Empty,
        System.Windows.Media.Imaging.BitmapSizeOptions.FromEmptyOptions());
    }
    finally
    {
        DeleteObject(intPtr);
    }

    DeleteObject(intPtr);

    return bitmapSource;
}

这只是位图部分 - 实际加载按以下方式完成:

DispatcherTimer Timer = new DispatcherTimer();

public MainWindow()
{

        this.Timer.Tick += new EventHandler(Timer_Tick);
        this.Timer.Interval = new TimeSpan(0, 0, 0, 1);

        this.Timer.Start();
}
void Timer_Tick(object sender, EventArgs e)
{
    WorldMap.Draw();
    map.Source = WorldMap.BitMapSource;
}

这只是重要的部分 - 我希望我的问题是可以理解的,但只是为了澄清和重复:

我需要一个WPF图像来更新“每一帧”或每次特定值更改。

之前我的问题可能已得到解答,但我找不到任何有用的东西,也无法找到适合这种情况的东西。

BTW更频繁地启动定时器会在加载时产生错误,但确切的错误代码,我不记得了,我似乎无法再创建它 - 从来没有这可能不是最实际的做法。

编辑:

为了澄清,这就是我现在所得到的:http://imgur.com/EIiSRFQ 我不想要任何想象 - 这只是个人项目的编程和数学,如果我可以想象我在2D平面上“移动”的对象,那就更容易了。 现在我正在玩物理和重力,试图用物理学创建一个简单的太阳系。这些只是侧面项目,以便在我太累而不能在我的主项目上工作时更好地了解不同的工具。

1 个答案:

答案 0 :(得分:1)

我希望将位图的可视元素表示为WPF中的控件。这样,您可以直接更新它们,也可以随时更新它们,而无需创建位图和渲染它的开销。

由于您只更新了价值变化,因此效果会更高。

为了证明这一点,创建一个控件......

<UserControl x:Class="Sample_Chart.Views.CodeBehindChart"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         >
    <Canvas x:Name="LayoutRoot" />
</UserControl>

这很简单。接下来编辑文件背后的代码......

public partial class CodeBehindChart : UserControl
{
    public CodeBehindChart()
    {
        InitializeComponent();
        Respond();
    }

    private async void Respond()
    {
        await Task.Delay(2000);
        Random r = new Random();

        while (true)
        {
            this.LayoutRoot.Children.Clear();

            for (int i = 0; i < 100; i++)
            {
                Rectangle rectangle = new Rectangle();
                rectangle.SetValue(Canvas.LeftProperty, r.NextDouble() * this.LayoutRoot.ActualWidth);
                rectangle.SetValue(Canvas.TopProperty, r.NextDouble() * this.LayoutRoot.ActualHeight);

                rectangle.Width = 2;
                rectangle.Height = 2;
                rectangle.Fill = Brushes.Black;

                this.LayoutRoot.Children.Add(rectangle);
            }

            await Task.Delay(500);
        }
    }
}

在这个代码背后,我们有一个异步void方法,首先等待2秒(可选),然后在控件内的随机位置创建100个可视元素。它每1/2秒刷新一次。

如果您做了同样的事情,但是基于这些位置,尺寸和填充 - 甚至使用不同的形状 - 我认为您将拥有高性能,可扩展且易于扩展的解决方案以满足您的要求。

在下一阶段进行控制并从ViewModel进行控制将需要更多地考虑哪个适用于您的第一个项目&#39; - 虽然是一个有趣的,可能是一个雄心勃勃的步骤;)