在后台工作程序中显示 WPF 图像

发布于 2024-10-16 17:26:45 字数 1796 浏览 0 评论 0原文

我正在使用 WPF 3.5。

我在backgroundworker_DoWork 事件中有while 循环,它将连续从DSLR 流式传输图像。

最初,流式传输的图像将显示在 PictureBox 中

<Grid>
    <WindowsFormsHost VerticalAlignment="Top" Background="Transparent" Height="500">
        <wf:PictureBox x:Name="picLiveView" />
    </WindowsFormsHost>
</Grid>

这是背后的代码:

        while (!liveViewExit)
        {
            try
            {
                if (picImage != null)
                    lock (mylock)
                    {
                        this.picLiveView.Image = (Image)picImage.Clone();
                    }
            }
            catch
            {

            }
        }

这工作正常。

但是,当我尝试将 PictureBox 更改为 WPF 图像控件时,在将 BitmapImage 分配给 WPF 图像控件时出现此错误:

{“调用线程无法访问此对象,因为另一个线程拥有它。”}

        MemoryStream ms = new MemoryStream();
        bmp.Save(ms, ImageFormat.Png);
        ms.Position = 0;
        BitmapImage bi = new BitmapImage();
        bi.BeginInit();
        bi.StreamSource = ms;
        bi.EndInit();

        try
        {
            if (bi != null)
            {
                this.imageBox.Source = bi;
            }
        }
        catch
        {

        }

为什么 . NET 2 PictureBox 控件可以工作,而 .NET 3.5 WPF Image 控件不能工作?

我尝试了这段代码:

BackgroundWorker bg = new BackgroundWorker();
Dispatcher disp = Dispatcher.CurrentDispatcher;
bg.DoWork += (sender, e) =>
{
    // load your data
    disp.Invoke(new Action(/* a method or lambda that do the assignment */));
}
bg.RunWorkerCompleted += anotherMethodOrLambda; // optional
bg.RunWorkerAsync(/*an argument object that will be visible in e.Argument*/);

它没有任何错误,但图像不刷新。 while 循环使应用程序没有响应。

I am using WPF 3.5.

I have while loop in a backgroundworker_DoWork event, which will continuously stream images from a DSLR.

Initially, the streamed image will be displayed in a PictureBox

<Grid>
    <WindowsFormsHost VerticalAlignment="Top" Background="Transparent" Height="500">
        <wf:PictureBox x:Name="picLiveView" />
    </WindowsFormsHost>
</Grid>

Here is the code behind:

        while (!liveViewExit)
        {
            try
            {
                if (picImage != null)
                    lock (mylock)
                    {
                        this.picLiveView.Image = (Image)picImage.Clone();
                    }
            }
            catch
            {

            }
        }

This works fine.

However, when I try to change the PictureBox to WPF Image control, I have this error when I assigned the BitmapImage to the WPF image control:

{"The calling thread cannot access this object because a different thread owns it."}

        MemoryStream ms = new MemoryStream();
        bmp.Save(ms, ImageFormat.Png);
        ms.Position = 0;
        BitmapImage bi = new BitmapImage();
        bi.BeginInit();
        bi.StreamSource = ms;
        bi.EndInit();

        try
        {
            if (bi != null)
            {
                this.imageBox.Source = bi;
            }
        }
        catch
        {

        }

Why the .NET 2 PictureBox control works while .NET 3.5 WPF Image control doesn't?

I tried this code:

BackgroundWorker bg = new BackgroundWorker();
Dispatcher disp = Dispatcher.CurrentDispatcher;
bg.DoWork += (sender, e) =>
{
    // load your data
    disp.Invoke(new Action(/* a method or lambda that do the assignment */));
}
bg.RunWorkerCompleted += anotherMethodOrLambda; // optional
bg.RunWorkerAsync(/*an argument object that will be visible in e.Argument*/);

It doesn't have any error, but the image doesn't refresh. The while loop make the application not responding.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

日裸衫吸 2024-10-23 17:26:45

您需要在主线程中实例化一个 Dispatcher 对象,并在后台工作程序中使用它,调用它的 Invoke 方法。

这是代码示例:

BackgroundWorker bg = new BackgroundWorker();
Dispatcher disp = Dispatcher.CurrentDispatcher;
bg.DoWork += (sender, e) =>
{
    // load your data
    disp.Invoke(new Action(/* a method or lambda that do the assignment */));
}
bg.RunWorkerCompleted += anotherMethodOrLambda; // optional
bg.RunWorkerAsync(/*an argument object that will be visible in e.Argument*/);

you need to instantiate a Dispatcher object in main thread, and use it in the background worker, calling it's Invoke method.

Here's a sample of code:

BackgroundWorker bg = new BackgroundWorker();
Dispatcher disp = Dispatcher.CurrentDispatcher;
bg.DoWork += (sender, e) =>
{
    // load your data
    disp.Invoke(new Action(/* a method or lambda that do the assignment */));
}
bg.RunWorkerCompleted += anotherMethodOrLambda; // optional
bg.RunWorkerAsync(/*an argument object that will be visible in e.Argument*/);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文