Search code examples
c#wpfwpf-controlswebcamdirectshow.net

how to host output from a Webcam inside of a WPF ImageControl using directShow


I want to display WEBCAM output to an IMAGE control in WPF while the user positions his/herself to take a passport. I am using the DirectShow Library and I can capture the Image and place it in the Image control but the Image control remains blank till i capture the Image. Please how can i ensure that the image control shows the webcam output before the user captures his/her image?. Thanks

this is the function that i feel controls what i want to achieve

private void ConfigVideoWindow(System.Windows.Controls.Image hControl)
    {
        HwndSource source = (HwndSource)HwndSource.FromVisual(hControl);
        int hr;

        IVideoWindow ivw = m_FilterGraph as IVideoWindow;

        // Set the parent
        hr = ivw.put_Owner(source.Handle);//i need to create an handle for the image control and pass it here. but i cannot do that
        DsError.ThrowExceptionForHR(hr);

        // Turn off captions, etc
        hr = ivw.put_WindowStyle(WindowStyle.Child | WindowStyle.ClipChildren | WindowStyle.ClipSiblings);
        DsError.ThrowExceptionForHR(hr);

        // Yes, make it visible
        hr = ivw.put_Visible(OABool.True);
        DsError.ThrowExceptionForHR(hr);

        // Move to upper left corner
        Rectangle rc = new Rectangle();// changed from hControl.ClientRectangle
        hr = ivw.SetWindowPosition(0, 0, Convert.ToInt32(hControl.Height), Convert.ToInt32(hControl.Width));
        DsError.ThrowExceptionForHR(hr);
    }

i have commented the line that i think my problem is coming from. Thanks for your assistance


Solution

  • i finally figured how to do it. i had to use a windowsformhost to host a windows form picture box in the grid of my xaml code like this

            <WindowsFormsHost Name="ima" HorizontalAlignment="Left" Height="300" Margin="98,105,0,0" VerticalAlignment="Top" Width="350" Background="Black" >
    
            </WindowsFormsHost>
    

    then i added the picture box in the constructor of this xaml page like this

    // Create the interop host control.
            System.Windows.Forms.Integration.WindowsFormsHost host =
                new System.Windows.Forms.Integration.WindowsFormsHost();
    
            // Create the PictureBox control.
            PictureBox picBox = new PictureBox();
            picBox.Width = 350;
            picBox.Height = 300;
            // Assign the MaskedTextBox control as the host control's child.
            ima.Child = picBox;
    
            // Add the interop host control to the Grid
            // control's collection of child controls.
            this.grid1.Children.Add(host);
    

    then i modified the function in my question to this

    private void ConfigVideoWindow(System.Windows.Forms.PictureBox picBox)
        {
            int hr;
    
            IVideoWindow ivw = m_FilterGraph as IVideoWindow;
    
            // Set the parent
            hr = ivw.put_Owner(picBox.Handle);
            DsError.ThrowExceptionForHR(hr);
    
            // Turn off captions, etc
            hr = ivw.put_WindowStyle(WindowStyle.Child | WindowStyle.ClipChildren | WindowStyle.ClipSiblings);
            DsError.ThrowExceptionForHR(hr);
    
            // Yes, make it visible
            hr = ivw.put_Visible(OABool.True);
            DsError.ThrowExceptionForHR(hr);
    
            // Move to upper left corner
            Rectangle rc = picBox.ClientRectangle;
            hr = ivw.SetWindowPosition(0, 0, rc.Right, rc.Bottom);
            DsError.ThrowExceptionForHR(hr);
        }
    

    i hope this helps somebody. Note the window that contains the xaml page you placed your windowsformhost should not have transparency set to true, if not, it will not show.