Jump to content
  • Advertisement
Sign in to follow this  

[DXSHOW] Get webcam bitmap

This topic is 1791 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts



Trying to figure out, how to get a bitmap from webcam output.

The problem is in colours. it seems a webcam output is YUV color space and i am not sure, how to display it right as most other examples are not care about that.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using DirectShowLib;
using System.Runtime.InteropServices;
using System.Drawing.Imaging;

namespace WindowsFormsApplication3
    public partial class Form1 : Form
        [DllImport("kernel32.dll", EntryPoint = "CopyMemory", SetLastError = false)]
        public static extern void CopyMemory(IntPtr dest, IntPtr src, uint count);

        public IGraphBuilder gb;
        public ICaptureGraphBuilder2 cgb;
        public IBaseFilter filter;
        static SampleGrabberCallback cb;
        VideoInfoHeader header;
        static Form1 thisform;

        public class SampleGrabberCallback : ISampleGrabberCB

            int ISampleGrabberCB.SampleCB(Double SampleTime, IMediaSample sample)
                return 0;

            int ISampleGrabberCB.BufferCB( Double SampleTime, IntPtr dataPtr, Int32 BufferLen ) 
                Bitmap bitmap = new Bitmap(640, 480, 640*3, PixelFormat.Format24bbp, dataPtr);

                Graphics g = thisform.panel1.CreateGraphics();
                g.DrawImageUnscaled(bitmap, 0, 0, 640, 480);

                return 0;

        public Form1()
            thisform = this;

            DsDevice[] videoInputDevices = DsDevice.GetDevicesOfCat(FilterCategory.VideoInputDevice);            
            object obj = null; Guid iid = typeof(IBaseFilter).GUID;
            videoInputDevices[1].Mon.BindToObject(null, null, ref iid, out obj);
            filter = (IBaseFilter)obj;
            ISampleGrabber grabberFilter = (ISampleGrabber)new SampleGrabber();
            IBaseFilter baseGrabber = (IBaseFilter)grabberFilter;


            ((IAMCameraControl)filter).Set(CameraControlProperty.Exposure, 0, CameraControlFlags.Auto);

            gb  = (IGraphBuilder) new FilterGraph();
            cgb = (ICaptureGraphBuilder2) new CaptureGraphBuilder2();

            IEnumPins pins;
            IPin [] inputPin = { null };
            IPin [] outputPin = { null };

            filter.EnumPins(out pins);
            pins.Next(1, outputPin, IntPtr.Zero);

            baseGrabber.EnumPins(out pins);
            pins.Next(1, inputPin, IntPtr.Zero);

            gb.AddFilter(filter, "First Filter");
            gb.AddFilter(baseGrabber, "Grabber Filter");
            gb.Connect(outputPin[0], inputPin[0]);


            AMMediaType media = new AMMediaType();
            media.majorType = MediaType.Video;
            media.subType = MediaSubType.RGB24;
            media.formatType = FormatType.VideoInfo;

            header = (VideoInfoHeader)Marshal.PtrToStructure(media.formatPtr, typeof(VideoInfoHeader)); 

            cb = new SampleGrabberCallback();          

            grabberFilter.SetCallback(cb, 1);

            cgb.RenderStream(PinCategory.Preview, MediaType.Video, filter, null, null);
            ((IVideoWindow)gb).put_WindowStyle(WindowStyle.Child | WindowStyle.ClipChildren);
            ((IVideoWindow)gb).SetWindowPosition(0, 0, this.panel1.Width, this.panel1.Height);

        private void OnResize(object sender, EventArgs e)
            ((IVideoWindow)gb).SetWindowPosition(0, 0, this.panel1.Width, this.panel1.Height);

This is my code, it enumerate video devices ( my default device is number 1, you should use 0, if you have only one device ), SampleGrabber calls callback function and i can get a buffer there.


I tried most formats Format24bbp, Format16bpp565 .. and .. ok, if it's YUV, i should convert it, but i though i can just specify type in mediatype as examples are doing it.


I also attached full source with directshownet library. if someone has a time to check, i will be very happy as i am trying to figure it out whole a day, reading tutorials, samples ... smile.png


Thank you very much

Edited by wh1sp3rik

Share this post

Link to post
Share on other sites

I just got an answer on StackOverflow.


I set up SampleGrabber filter too late. I should set it up before connecting and that was the problem.

Share this post

Link to post
Share on other sites
Sign in to follow this  

  • Advertisement

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!