We have some thrid party controls.
Instead we could write it on our own.
for ex :
Create a Movie Maker Class:
public delegate void RenderFrameDelegate(int frame, AutoResetEvent doneWaitHandle);
public delegate void CaptureCompleteDelegate(MovieMaker mm);
public class MovieMaker
{
private int _totalFrames;
private Control _captureControl;
private RenderFrameDelegate _renderMethod;
private CaptureCompleteDelegate _captureComplete;
private AutoResetEvent _waitHandle = new AutoResetEvent(false);
private bool CaptureSameFrameTwice;
//private string _imagePath = @"C:\Video Capture Test";
//private DateTime _fileName;
//public MovieMaker(Control captureControl, int totalFrames, RenderFrameDelegate renderMethod, CaptureCompleteDelegate captureComplete, DateTime filename)
public MovieMaker(Control captureControl, int totalFrames, RenderFrameDelegate renderMethod, CaptureCompleteDelegate captureComplete, bool shallCaptureTwice)
{
_captureControl = captureControl;
_totalFrames = totalFrames;
_renderMethod = renderMethod;
_captureComplete = captureComplete;
//_fileName = filename;
Frames = new List<byte[]>();
CaptureSameFrameTwice = shallCaptureTwice;
}
public void Start()
{
IsCapturing = true;
IsComplete = false;
ThreadPool.QueueUserWorkItem(RunOnBackgroundThread);
}
private void RunOnBackgroundThread(object state)
{
int i = 0;
int captureCount;
int capturedCount = 0;
bool firstFrame = true;
if (CaptureSameFrameTwice)
{
captureCount = 2;
}
else
{
captureCount = 1;
}
while (i < _totalFrames)
{
// Call delegate to render the control
_captureControl.Invoke((ThreadStart)delegate { _renderMethod(i, _waitHandle); });
// Wait to finish
_waitHandle.WaitOne();
// Capture image
_captureControl.Invoke((ThreadStart)delegate
{
Application.DoEvents();
using (Image img = new Bitmap(_captureControl.Width, _captureControl.Height))
using (MemoryStream stream = new MemoryStream())
{
Graphics g = Graphics.FromImage(img);
Point pt = _captureControl.PointToScreen(new Point(0, 0));
g.CopyFromScreen(pt, new Point(0, 0), _captureControl.ClientSize);
img.Save(stream, ImageFormat.Jpeg);
// img.Save(_imagePath + "\\" + _fileName.ToString("yyyyMMddhhmmss") +i.ToString()+".jpg",ImageFormat.Jpeg);
Frames.Add(stream.ToArray());
}
});
capturedCount += 1;
if (capturedCount == captureCount)
{
capturedCount = 0;
i++;
}
if (captureCount == 1 && firstFrame == true)
{
i--;
firstFrame = false;
}
}
// Raise complete event
_captureControl.Invoke((ThreadStart)delegate
{
IsCapturing = false;
IsComplete = true;
_captureComplete(this);
});
}
public List<byte[]> Frames { get; set; }
public bool IsCapturing { get; private set; }
public bool IsComplete { get; private set; }
and then in ur form where want to capture use the below lines:
MovieMaker mc = new MovieMaker(this, videoFrameCount, RenderFrame, CaptureComplete, ShallCaptureTwice);
mc.Start();
private void RenderFrame(int frame, AutoResetEvent waitHandle)
{
if (frame <= videoFrameCount)
{
if (frame == videoFrameCount - 1)
DisableProgressBar();
waitHandle.Set();
}
}
private void CaptureComplete(MovieMaker mm)
{
// Save the data where want to save
}