【发布时间】:2018-09-17 22:17:54
【问题描述】:
我想简单地捕捉并在我的视图上显示一张相机图片,每秒更新一次。但是,绑定到我的 Bitmapsource CurrentFrame的图像容器在运行时保持空白。
这是我目前的代码(主要来自an answer of another thread with similar topic:
public class CameraViewModel : ViewModelBase
{
public CameraViewModel()
{
StartVideo();
}
private DispatcherTimer Timer { get; set; }
private VideoCapture Capture { get; set; }
private BitmapSource currentFrame;
public BitmapSource CurrentFrame
{
get { return currentFrame; }
set
{
if (currentFrame != value)
{
currentFrame = value;
SetProperty(ref currentFrame, value);
}
}
}
private void StartVideo()
{
//CurrentFrame = new BitmapImage(new Uri("C:\\Users\\Johannes\\Pictures\\Camera Roll\\asdf.bmp")) as BitmapSource;
Capture = new VideoCapture();
Timer = new DispatcherTimer();
//framerate of 10fps
Timer.Interval = TimeSpan.FromMilliseconds(1000);
Timer.Tick += new EventHandler(async (object s, EventArgs a) =>
{
//draw the image obtained from camera
using (Image<Bgr, byte> frame = Capture.QueryFrame().ToImage<Bgr, byte>())
{
if (frame != null)
{
CurrentFrame = ToBitmapSource(frame);
}
}
});
Timer.Start();
}
public static BitmapSource ToBitmapSource(IImage image)
{
using (System.Drawing.Bitmap source = image.Bitmap)
{
IntPtr ptr = source.GetHbitmap(); //obtain the Hbitmap
BitmapSource bs = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(ptr, IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
DeleteObject(ptr); //release the HBitmap
return bs;
}
}
/// <summary>
/// Delete a GDI object
/// </summary>
[DllImport("gdi32")]
private static extern int DeleteObject(IntPtr o);
}
为了更好地理解一些事情:
- ViewModelBase 类结合并处理 INotifyPropertyChange 事件。
- 数据绑定正在工作!我已经测试过了
它,通过将 bmp 文件分配给
CurrentFrameStartVideo()Method - 图像在运行时显示在 GUI 中。 -
SetProperty()Method 按预期每 1000 毫秒触发一次。 - 当我将文件分配给
CurrentFrame以测试数据绑定时,我 看到它似乎是BitmapImage类型——也许这就是 问题出在哪里??但是从我收集到的信息来看, BitmapSource 应该可以工作并在 WPF 视图中显示... - 摄像头捕获的帧不为空。我试着写 直接到图像文件,它显示正确的内容为 预计。
编辑: 为了完整起见,这里也是视图的负责部分:
<UserControl.Resources>
<ResourceDictionary>
<local:CameraViewModel x:Key="vm" />
</ResourceDictionary>
</UserControl.Resources>
<Grid DataContext="{StaticResource vm}">
<Image Source="{Binding CurrentFrame}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/>
</Grid>
【问题讨论】:
-
当我将文件分配给 CurrentFrame... 你的意思是图像是可见的?
-
@Clemens 是的,我没有使用从相机捕获的帧,而是加载了一个 bmp 文件并将其分配给
CurrentFramevariable。这样做 bmp 图像在 GUI 中可见。 -
为什么 Tick 处理程序是异步的?似乎没有任何等待。
-
您确定 Capture 确实返回非空图像,即不完全透明的图像吗?
-
是的,我还测试了将捕获的帧直接写入文件 - 它显示了正确的内容。 - 我将在原始问题中进行编辑。