How to draw on an unfilled box on a video stream u

2019-07-08 08:24发布

问题:

I am using dshownet(first time) and C#. I have got a sample to take the web cam input and display it on a form. I now need to draw a rectangle on top of the video stream using the mouse. (the intent is to track what is inside the box from there onwards).

I heard that there is something called VMR. So I went to the dshownet samples and went through them. I didnt find any samples that use the mouse to overlay a shape on the video stream. Someone on here suggested to use colorkey. Another person said to use GDI+ and mouse handling. I tried to compile the DXLogo sample but got this error :


Error 1 Cannot create an instance of the abstract class or interface 'System.Drawing.Image' C:\Documents and Settings\TLNA\Desktop\Final Year Project\Libraries\DirectShow library 2\DirectShowSamples-2010-February\Samples\Capture\DxLogo\Capture.cs 128 32 DxLogo-2008


for the code section:


   if (fileName.Length > 0)
           {
               m_Bitmap = new Image(fileName); // error happened here

               Rectangle r = new Rectangle(0, 0, m_Bitmap.Width, m_Bitmap.Height);
               m_bmdLogo = m_Bitmap.LockBits(r, ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
           }

I know that I must go through the Bitmap9 Interface. But I really dont know where to start. Should I read the Directshow API docs.

btw I also have the book Programming Microsoft Directshow for digital video and television. I started reading that book and stopped after a few pages since the code is mainly in C++. Should I continue to read this is book ? How can I accomplish the certain mentioned tasks in C# ?

Any suggestions as how to draw on the video. Some useful links(tutorials) would be helpful.

Many Thanks Tlna

回答1:

I'm not sure why the DirectShow sample doesn't compile, but you may be able to change the problem line:

m_Bitmap = new Image(fileName);

to this:

m_Bitmap = new Bitmap(fileName);

and get it to work.

You're actually facing a pretty difficult problem here. DirectShow renders a video by drawing a series of still frames to a device context (like a PictureBox or a Form, or even the screen) many times a second (depending on whatever the frame rate is). You (as a programmer) can also (easily) render graphics directly to this same device context.

However, in order to make your drawn box appear over top of a running video, your code needs to draw the rectangle immediately after DirectShow draws each frame of the video; otherwise, the next frame will obliterate your rectangle. DirectShow objects probably have some sort of frame rendering event that you can handle, and then inside the event handler you just re-draw your box (based on the initial and current mouse coordinates, which you can get from the MouseDown and MouseMove events of whatever control you're drawing on).

Update: I just took a look at my code from when I was playing around with DirectShow.NET, and it looks like there is an event (DsEvCode.Repaint) that you could hook into and use to draw your box.

I haven't looked at the code sample you're working with, but do a search and see if you can find an OnGraphNotify() method in your code, you should be able to add something like this:

if (code == DsEvCode.Repaint)
{
    // draw the box here
}

Presumably, this event is fired after each frame of the video is rendered, so if you redraw your box here every time it will appear as if the box is persisting.