See my answer here for help. Emgu Capture plays video super fast
But this should do when you ask, I used a list to store images that you can use in an array, but you need to know how big your avi file is.
Timer My_Time = new Timer(); int FPS = 30; List<Image<Bgr,Byte>> image_array = new List<Image<Bgr,Byte>>(); Capture _capture; public Form1() { InitializeComponent(); //Frame Rate My_Timer.Interval = 1000 / FPS; My_Timer.Tick += new EventHandler(My_Timer_Tick); My_Timer.Start() _capture = new Capture("test.avi"); } private void My_Timer_Tick(object sender, EventArgs e) { Image<Bgr, Byte> frame = _capture.QueryFrame(); if (frame != null) { imageBox.Image = _capture.QueryFrame(); image_array.Add(_capture.QueryFrame().Copy()); } else { My_Timer.Stop(); { }
It was intended to play a video file with a responsible course, but since you are just converting, you could use the Application.Idle method as easily as this ...
List<Image<Bgr,Byte>> image_array = new List<Image<Bgr,Byte>>(); Capture _capture; public Form1() { InitializeComponent(); //Frame Rate _capture = new Capture("test.avi"); Application.Idle += ProcessFrame; } private void ProcessFrame(object sender, EventArgs arg) { Image<Bgr, Byte> frame = _capture.QueryFrame(); if (frame != null) { image_array.Add(frame.Copy()); } else { Application.Idle -= ProcessFrame;// treat as end of file } }
You need to be careful that you get an error message at the end of the file error. You can always use the try catch statement to catch the specific error it will give instead of simply completing the conversion.
If you use an array of images to use, you will have to iterate over the file, increasing the variable and counting frames, and then create an array of images before converting the video file into an array.
[EDIT]
As requested, this is a version of the method for extracting all frames from a video file, which I did not test in a large video file, since I expect the program to crash, as this will require a lot of memory.
private List<Image<Bgr, Byte>> GetVideoFrames(String Filename) { List<Image<Bgr,Byte>> image_array = new List<Image<Bgr,Byte>>(); Capture _capture = new Capture(Filename); bool Reading = true; while (Reading) { Image<Bgr, Byte> frame = _capture.QueryFrame(); if (frame != null) { image_array.Add(frame.Copy()); } else { Reading = false; } } return image_array; }
Alternatively, I understand that you might want to record 10 seconds of video from a webcam so that this method does this, I used a stopwatch, since the while loop forbids using a timer, unless your application is multithreading
private List<Image<Bgr, Byte>> GetVideoFrames(int Time_millisecounds) { List<Image<Bgr,Byte>> image_array = new List<Image<Bgr,Byte>>(); System.Diagnostics.Stopwatch SW = new System.Diagnostics.Stopwatch(); bool Reading = true; Capture _capture = new Capture(); SW.Start(); while (Reading) { Image<Bgr, Byte> frame = _capture.QueryFrame(); if (frame != null) { image_array.Add(frame.Copy()); if (SW.ElapsedMilliseconds >= Time_millisecounds) Reading = false; } else { Reading = false; } } return image_array; }
and it will look like this:
List<Image<Bgr, Byte>> Image_Array = GetVideoFrames(10000); //10 Secounds
Hope this helps,
Greetings
Chris