2019年12月12日 星期四

WPF webcam capture : 呼叫執行緒無法存取此物件,因為此物件屬於另一個執行緒

Ref: 1.  https://ponchi961.pixnet.net/blog/post/199057831
  2. https://github.com/emgucv/emgucv/blob/master/Emgu.CV.Example/CameraCapture/CameraCapture.cs


VS2017 @ Windows 10x64 : NET.Framework 4.6.1


//---xaml
<Window x:Class="wk1401.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:wk1401"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <Image Name="imageBox1"/>
    </Grid>
</Window>
//---xaml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace wk1401
{
    // nuget add emgu.cv
    // ref add System.ServiceModel 4.0
    using Emgu.CV;
    using Emgu.CV.CvEnum;
    using Emgu.CV.Structure;
    using Emgu.Util;
    using System.Drawing;
    using System.IO;
    /// <summary>
    /// MainWindow.xaml 的互動邏輯
    /// </summary>
    public partial class MainWindow : Window
    {
        private VideoCapture _capture = null;
        private Mat _frame;
        public MainWindow()
        {
            InitializeComponent();
            this.Closing += MainWindow_Closing;
            _capture = new VideoCapture();
            _capture.ImageGrabbed += _capture_ImageGrabbed;
            _frame = new Mat();
            _capture.Start();
        }

        private void MainWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            _capture.Dispose();
        }

        private void _capture_ImageGrabbed(object sender, EventArgs e)
        {
            if (_capture != null && _capture.Ptr != IntPtr.Zero)
            {
                _capture.Retrieve(_frame, 0);
                this.Dispatcher.Invoke((Action)(() =>
                {
                    // your code or function here.
                    // https://ponchi961.pixnet.net/blog/post/199057831
                    imageBox1.Source = ConvertBitmapToImageSource(_frame.Bitmap);
                }));
             
            }
        }
        private ImageSource ConvertBitmapToImageSource(Bitmap imToConvert)
        {
            Bitmap bmp = new Bitmap(imToConvert);
            MemoryStream ms = new MemoryStream();
            bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Bmp);
            BitmapImage image = new BitmapImage();
            image.BeginInit();
            ms.Seek(0, SeekOrigin.Begin);
            image.StreamSource = ms;
            image.EndInit();
            ImageSource sc = (ImageSource)image;
            return sc;
        }
    }
}


//---- webcam @ 3D
// Add helixtoolkit.wpf.dll
//-- xaml
<Window x:Class="wk1401.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:wk1401"
        xmlns:h="http://helix-toolkit.org/wpf"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <h:HelixViewport3D>
            <h:DefaultLights/>
            <ModelVisual3D>
                <ModelVisual3D.Content>
                    <Model3DGroup >
                        <Model3DGroup.Children>
                            <DirectionalLight Color="#FFFFFFFF" Direction="3,-4,5" />
                            <GeometryModel3D>
                                <GeometryModel3D.Geometry>
                                    <MeshGeometry3D
              Positions="-1 -1 0  1 -1 0  -1 1 0  1 1 0"
              Normals="0 0 1  0 0 1  0 0 1  0 0 1"
              TextureCoordinates="0 1  1 1  0 0  1 0   "
              TriangleIndices="0 1 2  1 3 2" />
                                </GeometryModel3D.Geometry>
                                <GeometryModel3D.Material>
                                    <DiffuseMaterial>
                                        <DiffuseMaterial.Brush>
                                            <ImageBrush x:Name="imageBox1"/>
                                        </DiffuseMaterial.Brush>
                                    </DiffuseMaterial>
                                </GeometryModel3D.Material>
                            </GeometryModel3D>
                        </Model3DGroup.Children>
                    </Model3DGroup>
                </ModelVisual3D.Content>
            </ModelVisual3D>
        </h:HelixViewport3D>
        <!--<Image Name="imageBox1"/>-->
    </Grid>
</Window>
//--- xaml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace wk1401
{
    // nuget add emgu.cv
    // ref add System.ServiceModel 4.0
    using Emgu.CV;
    using Emgu.CV.CvEnum;
    using Emgu.CV.Structure;
    using Emgu.Util;
    using System.Drawing;
    using System.IO;
    /// <summary>
    /// MainWindow.xaml 的互動邏輯
    /// </summary>
    public partial class MainWindow : Window
    {
        private VideoCapture _capture = null;
        private Mat _frame;
        public MainWindow()
        {
            InitializeComponent();
            this.Closing += MainWindow_Closing;
            _capture = new VideoCapture();
            _capture.ImageGrabbed += _capture_ImageGrabbed;
            _frame = new Mat();
            _capture.Start();
        }

        private void MainWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            _capture.Dispose();
        }

        private void _capture_ImageGrabbed(object sender, EventArgs e)
        {
            if (_capture != null && _capture.Ptr != IntPtr.Zero)
            {
                _capture.Retrieve(_frame, 0);
                this.Dispatcher.Invoke((Action)(() =>
                {
                    // your code or function here.
                    // https://ponchi961.pixnet.net/blog/post/199057831
                    //imageBox1.Source = ConvertBitmapToImageSource(_frame.Bitmap);
                    imageBox1.ImageSource = ConvertBitmapToImageSource(_frame.Bitmap);
                }));
               
            }
        }
        private ImageSource ConvertBitmapToImageSource(Bitmap imToConvert)
        {
            Bitmap bmp = new Bitmap(imToConvert);
            MemoryStream ms = new MemoryStream();
            bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Bmp);
            BitmapImage image = new BitmapImage();
            image.BeginInit();
            ms.Seek(0, SeekOrigin.Begin);
            image.StreamSource = ms;
            image.EndInit();
            ImageSource sc = (ImageSource)image;
            return sc;
        }
    }
}


1 則留言:

  1. Slots for Real Money | mcd.com
    Get a 여주 출장샵 list 충청북도 출장샵 of the best 보령 출장안마 real 파주 출장안마 money slots online for You won't find one for every casino game, except 충청북도 출장안마 the ones that are good for high rollers.

    回覆刪除