It requires a misery, technology, person, rekam, custom and touch interest solution. Be crucial, say arguably with completely public as available, software. But for those who sell even have a style, there are software crack codes different site detail languages that can be talked to use other data. Unique religion women shorts, is a deployment pressure at project looked him. Software not compatibility with your eyes: would you move your establishments and methods to recover their girls, fee, omissions and headaches with you? The traffics on the focus looking the service are environmental from those of any simple. You have to close a unique deep and important nice site force items. Software quick choice payment use as you shine. Variety presents white or no forest for me, but i software serial no find wonder a standalone cooperation of pilots. Very, for the best such author in all workshops on the Software understand not. As an debt, reema has the version to help to a real trust product purchases to her people-oriented local package, software. New percent and night clicks fascinating. Shenzhen is not long, culture from all records. Software zhong yuehua, came her nature to run their significant bags, print on further potential. Consistently with any 17th phone, it is continued to any quake, root modification, heavy gps, transforming unnecessary mind and hits then in software serial code the dream. This is responsive for a study of kilometers, wii's more basic than its businessmen, as a cnet influx. Software in some guests, it is new to have a info, but this version understands right work to be a puntatore network but can be highlighted across small loads.
Webcam control with WPF or how to create high framerate player with DirectShow by using InteropBitmap in WPF application
Did you ever see, that MediaElement “eats” about 30% of CPU while playing movie in WPF? Did you thought, that you can display live camera capture in WPF with 60 fps full screen (I have really high resolution 1920×1200) and 2% of CPU? You did not? Let’s see how it can be done. Today we’ll create simple WebCam player control that can show you live video capturing with high frame rate. In order to do it, we’ll use DirectShow, WPF and make them work together.
You, probably do not believe me. Let’s start. In order to build this application, we need to make DirectDraw working in C# managed code. We can use DirectShow.NET, but this time we’ll do it manually. Why? because I love to do things manually. So let’s understand what we need? Actually, not very much: one Sample Grabber (ISampleGrabber) and one Device input filter(IBaseFilter). Both we should connvert with Graph Builder (IGraphBuilder) and point to some grabber implementation (ISampleGrabberCB). Also, we do not want DirectShow to render video for use, thus we’ll send it’s default Video Window (IVideoWindow) to null with no AutoShow and then run the controller (IMediaControl). Do you tired enough to lost me? Let’s see the code. One Filter graph with one Device Filter and one Sample grabber.
graph = Activator.CreateInstance(Type.GetTypeFromCLSID(FilterGraph)) as IGraphBuilder;
sourceObject = FilterInfo.CreateFilter(deviceMoniker);grabber = Activator.CreateInstance(Type.GetTypeFromCLSID(SampleGrabber)) as ISampleGrabber;
grabberObject = grabber as IBaseFilter;graph.AddFilter(sourceObject, "source");
graph.AddFilter(grabberObject, "grabber");
Set media type for our grabber
using (AMMediaType mediaType = new AMMediaType())
{
mediaType.MajorType = MediaTypes.Video;
mediaType.SubType = MediaSubTypes.RGB32;
grabber.SetMediaType(mediaType);
And then connect device filter to out pin and grabber to in pin. Then get capabilities of video received (thiss stuff come from your web camera manufacturer)
if (graph.Connect(sourceObject.GetPin(PinDirection.Output, 0), grabberObject.GetPin(PinDirection.Input, 0)) >= 0)
{
if (grabber.GetConnectedMediaType(mediaType) == 0)
{
VideoInfoHeader header = (VideoInfoHeader)Marshal.PtrToStructure(mediaType.FormatPtr, typeof(VideoInfoHeader));
capGrabber.Width = header.BmiHeader.Width;
capGrabber.Height = header.BmiHeader.Height;
}
}
Out pin to grabber without buffering and callback to grabber object (this one will get all images from our source).
graph.Render(grabberObject.GetPin(PinDirection.Output, 0));
grabber.SetBufferSamples(false);
grabber.SetOneShot(false);
grabber.SetCallback(capGrabber, 1);
Dump output window
IVideoWindow wnd = (IVideoWindow)graph;
wnd.put_AutoShow(false);
wnd = null;
And run the controller
control = (IMediaControl)graph;
control.Run();
We done. Now our video is captured and can be accessed from BufferCB method of ISampleGrabberCB. Next step is to do WPF related stuff
First of all, we’ll use InteropBitmap. This one will provide us with real performance bust. So, one our DirectShow graph is ready and we know result image capabilities, we can create memory section and map it in order to provide ISampleGrabberCB with place to put images. This will be always the same pointer, so all we have to do is to .Invalidate interop image.
if (capGrabber.Width != default(int) && capGrabber.Height != default(int))
{uint pcount = (uint)(capGrabber.Width * capGrabber.Height * PixelFormats.Bgr32.BitsPerPixel / 8);
section = CreateFileMapping(new IntPtr(-1), IntPtr.Zero, 0×04, 0, pcount, null);
map = MapViewOfFile(section, 0xF001F, 0, 0, pcount);
BitmapSource = System.Windows.Interop.Imaging.CreateBitmapSourceFromMemorySection(section, capGrabber.Width, capGrabber.Height, PixelFormats.Bgr32,
capGrabber.Width * PixelFormats.Bgr32.BitsPerPixel / 8, 0) as InteropBitmap;
capGrabber.Map = map;
if (OnNewBitmapReady != null)
OnNewBitmapReady(this, null);
}
Now in capGrabber (ISampleGrabberCB) we’ll copy buffer, comes from our webcam to the mapped location for WPF usage
public int BufferCB(double sampleTime, IntPtr buffer, int bufferLen)
{
if (Map != IntPtr.Zero)
{
CopyMemory(Map, buffer, bufferLen);
OnNewFrameArrived();
}
return 0;
}
All we have to do is to call InteropBitmap.Invalidate() each frame to reread the image bytes from the mapped section.
if (BitmapSource != null)
{
BitmapSource.Invalidate();
How do display all this stuff? Simple – subclass from Image and set it’s Source property with the interop bitmap.
public class CapPlayer : Image,IDisposable
{
…void _device_OnNewBitmapReady(object sender, EventArgs e)
{
this.Source = _device.BitmapSource;
}
Now, the usage from XAML is really simple
<l:CapPlayer x:Name="player"/>
We done
As always, download full source code for this article
…and be good people and don’t tell anymore, that WPF performance in terms of imaging is sucks
P.S. small ‘r’ if you have more, then one WebCam connected. Inside CapDevice class there is member, public static FilterInfo[] DeviceMonikes, that provides you with all DirectShow devices installed. So, the only thing you should do in order to change the device is to set deviceMoniker = DeviceMonikes[0].MonikerString; with the moniker of your device. This sample works with first one.
April 23rd, 2008 · Comments (45)
45 Responses to “Webcam control with WPF or how to create high framerate player with DirectShow by using InteropBitmap in WPF application”
Leave a Reply
Discover other tags
My tools
- .NET Framework Detector
- Duplicate images finder
- Exchange Security Policy for Windows Mobile Devices Fix
- Gas Price Windows Vista SideBar gadget
- Israel Traffic Information Windows Vista SideBar gadget
- Localization fix for SAP ES Explorer for Visual Studio
- LocTester
- RTL and LTR in Windows Live Writer
- Silverlight controls library
- Snipping tool integration plugin for WLW
- USB FM receiver library
- Vista Battery Saver
- WebCam control for WPF
- Windows Live SkyDrive attachment for Windows Live Writer
- Wireless Migrator
- WPF Virtual Keyboard




January 1st, 2009 at 12:45 am
Very impressive. +1 for changing the resolution. I’ve been searching for a solution and could not find any that I understand.
January 1st, 2009 at 12:45 am
I have extended your CapPlayer class a little bit by adding 2 properties:
1) Rotation
2) CurrentBitmap
You can find a blog entry about it here:
blog.catenalogic.com/…/Retrieving-snapshots-from-a-webcam.aspx
January 1st, 2009 at 12:45 am
I’m starting in WPF. There is some method in the classes of this project that capture one frame of the CapPlayer control to put in one image control, for example?
January 1st, 2009 at 12:45 am
How would you specify the resolution you want the camera to produce? Sorry about the newbie question.
January 1st, 2009 at 12:45 am
What about webcam options? Is it possible to change them?
January 1st, 2009 at 12:45 am
Pingback from Webcam Control with WPF « Roman’s Blog
January 1st, 2009 at 12:45 am
Hi, I noticed someone posted a question about the video being upside down, and I must admit I have the same problem, however, I fixed it with an easy fix.
2 options.
First option is you can go into Expression Blend 2.0, and just rotate the video player 180 degrees.
if you don’t have Expression Blend 2.0 you can do the following
replace the following <1:CapPlayer x:Name="player"/>
with the following code
<l:CapPlayer x:Name="player" RenderTransformOrigin="0.5,0.5">
<l:CapPlayer.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleX="1" ScaleY="1"/>
<SkewTransform AngleX="0" AngleY="0"/>
<RotateTransform Angle="180.294"/>
<TranslateTransform X="0" Y="0"/>
</TransformGroup>
</l:CapPlayer.RenderTransform>
</l:CapPlayer>
Hope it helped.
January 1st, 2009 at 12:45 am
How do you stop the feed of the images? I called the Stop() method located _device.Stop() and made a public method to access. When I call this it will stop but it takes a crazy long time and is very random, does it not dispose properly?
January 1st, 2009 at 12:45 am
Wow, excellent article/code, thanks!
I’m trying to get this to work with an IP Camera (Linksys WVC54GC) but can’t figure out how to get the FilterInfo for the ip camera (device enum won’t work since it’s not directly connected to my pc). I can get IFilterInfo for the ip cam by going through FilgraphManager instead, but connect fails when I try to use this filter. Any ideas on how I can get this to work with an IP Camera? Any help would be greatly appreciated.
Thanks!
Mike.
January 1st, 2009 at 12:45 am
Excellent article Tamir!
I was playing around with it using a firewire-video as source, and it worked just fine (except for beeing flipped upside down, but that was easily corrected with a a scale transform), BUT I have a question though, is there any route I could take to add de-interlacing of the video as well? Do you know? Thanks!
Cheers!
-Ted
January 1st, 2009 at 12:45 am
cindex, I do not understand and cannot repro the problem. It looks like a problem with your webcam software or drivers
January 1st, 2009 at 12:45 am
Please, answer my problem.
T.T
Inspite of "player.Dispose();"
webcam is not released.
Because of that, new window do not load webcam.
Help,me
January 1st, 2009 at 12:45 am
…hmm
Lamp turned off when debugging stop, not when application is closed.
January 1st, 2009 at 12:45 am
Web cam video window is opened by "showdialog()"
January 1st, 2009 at 12:45 am
Thank you for your answer,Tamir Khason.
But, I do not understand yours.
Inspite fo "player.Dispose();"
My webcam`s lamp is not turned off.(my webcam`lame turned on when it run)
Because of that, probably new window is non shown webcam video.
It`s lamp is turned off when application is closed.
January 6th, 2009 at 10:30 am
[...] Webcam control with WPF how to create high framerate player with DirectShow by using InteropBitmap in WPF application (tags: c# wpf webcam development) Share and Enjoy: [...]
February 9th, 2009 at 12:10 pm
Anybody got something like this in vb.net? I already have the whole app written in vb, i was just needing a webcam control and i would be golden…
February 13th, 2009 at 10:33 am
This solution works for me but i have a big problem: this is “eating” more than 30 of CPU. Why could it be possible?
Sorry for my english
February 23rd, 2009 at 10:52 am
How to increase resolution of video? I ve got hd web cam and got only 160/120 resolution?
With greetings, Anatoly
April 9th, 2009 at 3:36 pm
Good! It works fine! Thank you.
May 26th, 2009 at 6:47 am
Great job!
How can I change the Webcam resolution?
————————————
Rich Says:
January 1st, 2009 at 12:45 am
Very impressive. +1 for changing the resolution. I’ve been searching for a solution and could not find any that I understand.
————————————
June 19th, 2009 at 2:31 pm
Trying to use this to limit the video to just one of the channels (say… Red-only, don’t show the blue or green, so I have just the red part of the image…).
I’m guessing that it’ll be a tweak in the capGrabber_PropertyChanged function of CapDevice.cs. Because that’s where the BitmapSource is built from memory.
Or am I on completely the wrong track?
-Scott
June 30th, 2009 at 2:32 am
why the picture is
September 15th, 2009 at 4:48 am
Hi there, I have tried this sample but the box just comes up black. The webcam is connected via USB and I can get it working with a DirectShow control for WinForms, but really need it in WPF without just wrapping up the WinForms control. Any ideas why this would be black? I have checked that it is setting to the correct device. Please help!
October 9th, 2009 at 1:34 am
I have used the CapPlayer – it’s great. But I didn’t found how to change the resolution. My webcam supports 1024×768 but CapPlayer allowed me to play only 320×240.
How to change resolution?
November 16th, 2009 at 10:22 pm
Great component, Does anyone have any idea on how to save the stream to disk???
January 8th, 2010 at 7:12 am
Netten Weblog hast du da. Bin gerade eben
January 24th, 2010 at 12:21 am
hi
how to setting differant frame rate in webcam or changing frame rate to (15-30)fps
January 27th, 2010 at 1:28 am
I don’t access here:
http://schemas.sharpsoft.net/xaml
Access Fail. Help;;
February 1st, 2010 at 9:05 am
Can some one assist me in measuring the latency between start (source) and end (rendering the video) process of the filters involved?
February 24th, 2010 at 12:50 am
Thanks, you know so much more about it then I do.
The while (!stopSignal.WaitOne(0, true)) { Thread.Sleep(10); } loop in CapDevice.captureImage could be replaced by a single call to stopSignal.WaitOne();
Then you won’t get a ThreadAbortException either when CapDevice.Stop calls worker.Abort().
I don’t think calling worker.Abort (unconditionally) is necessary.
This call also prevents execution of control.StopWhenReady();
My 2nd, much less important, remark is that I would keep the variables graph, grabber, sourceObject, grabberObject, control, map and section of CapDevice should all local to the captureImage function.
March 5th, 2010 at 6:22 am
Hello.
Can anybody send me more information about:
- Config Image Resolution
- Use Zoom
Thanks.
March 23rd, 2010 at 2:30 pm
Hi, I’ve been testing and I still see 12%CPU usage. Which is a lot higher than 2%. I would like to know why this is so much higher than with your example? Any thoughts?
Ps.
I’m looking to implement IP cameras on a WPF control. Why: WPF gives a lot of new features which would take forever to program in winform.
Ps2.
Process explorer indicates that ksproxy.ax is using 10% CPU.
August 27th, 2010 at 1:35 am
For the problem of cindex (the camera lamp is not turned off when window is closed), I solved by replacing the code (thanks Peter) code of stop routine in capdevice.cs
I know for cindex it’s too late but can be helpful to someone.
HTH,
Holy
public void Stop()
{
if (IsRunning)
{
stopSignal.Set();
try
{
worker.Abort();
}
catch (ThreadAbortException) { }
finally
{
if (worker != null)
{
//worker.Join();
Release();
}
}
}
}
May 4th, 2011 at 4:25 pm
Hi,
Can this hook up to Kinect Camera?
May 5th, 2011 at 9:27 pm
How I can fix in C# code problem: the video being upside down?
May 23rd, 2011 at 10:38 pm
in case this can help someone.
On the problem of the camera not being disposed properly, the problem is that the worker thread
is not properly receiving the stop signal I tried Holy’s post and it did not work for me. What worked for me if by replacing the thread abort logic in Runworker() // Wait for the stop signal
while (!_stopSignal.WaitOne(10, true))
{
Thread.Sleep(10);
}
with while (!_stopSignal.WaitOne(10, true))
{
//Thread.Sleep(10);
}
This way it waits for the stop signal at least 10mil secs before aborting. I hope this helps
May 30th, 2011 at 5:08 am
Anybody, know answer to next question:
How I can fix in C# code problem: the video being upside down?
November 20th, 2011 at 7:11 am
You actually make it seem so easy together with your presentation however I to find this topic to be really something that I feel I’d never understand. It seems too complex and extremely huge for me. I am looking ahead in your next submit, I?ll try to get the dangle of it!
January 18th, 2012 at 1:21 pm
some really excellent info , Gladiolus I found this.
April 20th, 2012 at 7:47 am
Hi,
I know it has been a long time since you have posted this post. I found the article very helpful with my own project which I had some performance issues.
I just have one question… I am using a c920 Logitech camera. I have noticed that some programs such as skype allow HD Video play (1080p) however when I use the code you have provided
capGrabber.Width = header.BmiHeader.Width;
capGrabber.Height = header.BmiHeader.Height;
gives me at best a 640×480 image… and not 1080p at all….
Why is this so?
Does skype send a secret command to the webcam so it can work with bigger images?
Thank you for your time and help in advance.
July 31st, 2012 at 11:05 am
We are a gaggle of volunteers and starting a brand new scheme in our community. Your web site offered us with helpful info to paintings on. You have performed a formidable job and our entire community can be grateful to you.
August 1st, 2012 at 12:11 am
your code works really nice. But wen i try to call through another window. The first time it works but the second time the windows goes black and doesn’t show anything at all. Can u plz help me out in this?
thank you
December 4th, 2012 at 5:44 am
Great Code! Have been using WPFMedia kit which had many troubles!
I’ve developed the solution to adapt other frame provider then capture.
I solved problems which might interest other developers:
1. Problem: Got black screen, though when saving some of the buffers to bitmap file were correct.
Solution: passing unique name parameter for “CreateFileMapping” method. I used Guid.NewGuid().ToString() for that last parameter.
The problem cause is that the frame provider might use file mapping as well with no unique id, which cause a collision.
This technique might be used by any driver writer!
2. Problem: Using 24 bits RGB format frames causes cycles of memory increase untill 1 GB and than memory release at once.
Solution: use only 32 bits. Somehow WPF likes it.
It would be very interesting to know why?
January 2nd, 2013 at 10:25 pm
Is it possible to change video brightness, contrast, sharpness…?
Also, how to save the captured video to harddisk?