Я хочу просто захватить и отобразить изображение с камеры на моем виде, обновляемое каждую секунду. Однако контейнер изображения, связанный с моим Bitmapsource CurrentFrame
, остается пустым во время выполнения.
Это мой код до сих пор (в основном взят из ответа другой ветки с похожей темой :
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-файл
CurrentFrame
в
StartVideo()
Метод - и изображение отображается в графическом интерфейсе во время выполнения.
- Метод
SetProperty()
срабатывает каждые 1000 мсек, как и ожидалось.
- Когда я назначил файл для
CurrentFrame
, чтобы проверить привязку данных, я
увидел, что это, кажется, типа BitmapImage
- может быть, там
проблема лежит ?? Однако из информации, которую я мог собрать,
BitmapSource должен работать и показываться в представлениях WPF ...
- Захваченный кадр с камеры не пустой. Я пытался написать это
непосредственно в файл изображения, и он показывает правильное содержимое как
ожидается.
Edit:
Для полноты здесь также ответственная часть представления:
<UserControl.Resources>
<ResourceDictionary>
<local:CameraViewModel x:Key="vm" />
</ResourceDictionary>
</UserControl.Resources>
<Grid DataContext="{StaticResource vm}">
<Image Source="{Binding CurrentFrame}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/>
</Grid>
Edit2: Ссылка на репозиторий Github для просмотра кода