如何从正在从另一个线程/程序写入的磁盘中不断刷新映像

时间:2016-03-14 18:13:36

标签: c# c++ wpf image mvvm

我有一些遗留的C / C ++代码,我试图快速集成到我的GUI中(由于复杂性和时间限制,CLI不是一个选项)。它会不断从相机输出~15fps的图像。我的想法是将图像写入磁盘并使用使用C#和WPF的GUI从我的程序中读取它。写入SSD的图像采用JPEG格式(虽然我可以在遗留代码中进行更改)并且只有240kB大,因此在性能方面它应该不是问题。

我最初的尝试是将图像源绑定到ViewModel内的图像文件名,然后使用RaisePropertyChanged到GUI来更新图像。不幸的是,这不起作用。从调试遗留代码来判断,这是因为我的GUI C#代码阻止了图像文件,遗留程序因此无法再写入它。我也在SO中找到了一个帖子,暗示这就是问题所在。

那么有没有办法实现我想做的事情?我查看了ImageSourceBitmapSource,因为它们应该允许我以非阻塞方式读取文件。但我无法弄清楚如何将它们作为源集成到我的ViewModel中,因为它们是抽象类,我收到错误Cannot create an instance of the abstract class of interface

如果有任何建议,我将不胜感激。代码示例当然会很棒。这是我的代码:

视图模型:

public class CameraViewModel : ViewModelBase
{
    private string imageSource;
    public string ImageSource
    {
        get { return imageSource; }
        set {
            if (!(value == imageSource))
            {
                imageSource = value;
                RaisePropertyChanged("ImageSource");
            }
        }
    }

    public CameraViewModel()
    {
        string fileName = @"./CurrentImage.jpg";
        ImageSource = fileName;

        Task.Factory.StartNew(() =>
        {
            while (true)
            {
                RaisePropertyChanged("ImageSource");
                Thread.Sleep(33);
            }
        });
    }
}

查看:

<UserControl x:Class="ProgramEditor.Views.CellCameraView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300"
             DataContext="{Binding Camera_VM, Source={StaticResource Locator}}">
    <Image Name="CameraImage" Height="150" Width="200" Stretch="Fill" Source="{Binding ImageSource}" />
</UserControl>

在遗留代码中编写图像的代码。添加了DeleteFile - 调用以进行调试:

void WriteCurrentImage(BYTE * pBuffer)
{
    bool rc;
    currentimage = cvCreateImageHeader(cvSize(VideoWidth, VideoHeight),IPL_DEPTH_8U, 1);
    currentimage->imageData = (char*)pBuffer;
    rc = DeleteFile( "./CurrentImage_tmp.jpg" ); // to test file access
    cout << "DeleteFile(CurrentImage_tmp) rc:" << rc << endl; // rc = 1; works
    cvSaveImage("./CurrentImage_tmp.jpg" ,currentimage);
    rc = DeleteFile( "./CurrentImage.jpg" ); // to test file access
    cout << "DeleteFile(CurrentImage) rc:" << rc << endl; // rc = 0; fails
    MoveFile("./CurrentImage_tmp.jpg","./CurrentImage.jpg");
    cout << "WriteCurrentImage(pBuffer); called." << endl;
}

0 个答案:

没有答案