我正在尝试使包含图像的 WPF 窗口连续显示 USB 相机捕获的帧。
在我的代码中,ViewModel 实例化了一个作为参数CameraServiceClass
传递的字段。然后,当事件被触发时,该字段被设置,但我不知道如何通知属性更改,因为事件是在内部触发和处理的。_frame
ref
NewFrame
CameraViewModel.Frame
_camera_service
问题是:
- 我应该使用这样的
ref
参数吗? CameraServiceClass
向 中添加一个事件,在类中收听它CameraViewModel
,并通过提高Frame
属性更改来处理它是一个好主意吗?如果是,我会怎么做?- 本身是否应该
CameraServiceClass
通知自定义 FrameReceived 事件并在事件参数中传递位图本身?如果是,我会怎么做?
我的课程是:
<Window x:Class="CameraGUI.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ap="clr-namespace:CameraGUI"
Title="MainWindow" Height="350" Width="525">
<Window.DataContext>
<ap:CameraViewModel/>
</Window.DataContext>
<Grid>
<Viewbox Stretch="Uniform">
<Image Source="{Binding Frame, Mode=OneWay}" />
</Viewbox>
</Grid>
</Window>
相机视图模型:
class CameraViewModel : ViewModelBase {
System.Drawing.Bitmap _frame_camera;
public System.Windows.Media.Imaging.BitmapImage Frame {
get {
if (_frame_camera != null) {
using(MemoryStream ms = new MemoryStream())
{
_frame_camera.Save(ms, ImageFormat.Bmp);
ms.Position = 0;
BitmapImage bitmapImage = new BitmapImage();
bitmapImage.BeginInit();
bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
bitmapImage.StreamSource = ms;
bitmapImage.EndInit();
bitmapImage.Freeze();
return bitmapImage;
}
} else return null;
}
}
CameraServiceClass _camera_service;
// CONSTRUTOR
public CameraViewModel() {
_camera_service = new CameraServiceClass(ref _frame_camera);
}
}
和CameraServiceClass:
public class CameraServiceClass
{
System.Drawing.Bitmap _frame;
VideoCaptureDevice videoSource;
// CONSTRUTOR
public CameraServiceClass(ref System.Drawing.Bitmap bitmap) {
_frame = bitmap;
var videoDevices = new FilterInfoCollection(FilterCategory.VideoInputDevice);
videoSource = new VideoCaptureDevice(videoDevices[0].MonikerString);
videoSource.NewFrame += new NewFrameEventHandler(video_NewFrame);
videoSource.Start();
}
private void video_NewFrame (object sender, NewFrameEventArgs eventArgs) {
System.Drawing.Bitmap bmp = (System.Drawing.Bitmap)eventArgs.Frame.Clone();
_frame = bmp;
}
}