Click here to Skip to main content
11,637,662 members (75,086 online)
Click here to Skip to main content

Extracting still pictures from movie files, with C#

, 23 Feb 2005 352.1K 18K 111
Rate this:
Please Sign up or sign in to vote.
Sample application to extract still pictures from most movie file formats.

Sample Image

Introduction

Pressing the "Print Screen" key while playing a movie file in Windows Media Player will not allow you to save the current frame. The sample application will save frames to JPEG files. It can extract frames from most movie file formats including *.wm? (Windows Media Player), *.avi, *.mpeg, *.mov (QuickTime), and *.dat (DivX). Commercial and shareware applications that provide this functionality exist but the code that I will show will let you build your own application that fits your exact needs.

Background

Pressing the "Print Screen" key while playing a movie file in Windows Media Player will not allow you to save the current frame. So I started to look for a simple way to grab a frame from movie files playing in the most common media applications (e.g., Windows Media Player, QuickTime, or DivX Player). It turned out to be more complicated than I originally thought. Hence, I decided to write up a sample application and submit it to CodeProject since I have used their resources quite often; it was a way to thank the people behind this site.

Microsoft approach to this problem would be using DirectShow but there is no managed equivalent of it. By digging in the DirectX documentation, I discovered the MediaDet class that is used in some VB samples. It is not the ideal solution but it is good enough for many situations. By wrapping the qedit.dll from the DirectShow Developer Runtime (which is included in the Extras of the DirectX SDK) in a managed assembly, I could make calls to MediaDetClass::WriteBitmapBits method that saves a frame from a movie file to a bitmap file.

Using the code

As already mentioned, the workhorse of the application is the WriteBitmapBits method of the class MediaDetClass. In order to be able to access this method, you need to add a reference (from Visual Studio menu, Project/Add Reference if you are using Visual Studio, or use tlbimp from the .NET Framework tools) to the qedit.dll. In the code for this application, I have included the managed assembly (named interop.dexterlib.dll which was created using VS).

To declare an object of the MediaDetClass, you'll see code like:

          MediaDetClass md = new MediaDetClass();
          md.Filename = "sample.mov";      
          md.CurrentStream = 0;
          string fBitmapName = "sample" + ".bmp" ;
          md.WriteBitmapBits( 0, 320, 240, fBitmapName );

After having called WriteBitmapBits, the MediaDetClass object is, as the DirectShow documentation says, in bitmap grab mode. The important thing to know about this is that you need to create a new MediaDetClass instance anytime you need to load a new movie (it is a little as if the properties of this class are "read only").

I have set the property CurrentStream to 0 and it was working with all the samples I have tried. Moreover, it seems that you can only write to a bitmap file. So in order to save disk space, I have added code to convert the bitmap file to a JPEG one. You have to remember that, even with our 100 Gig hard disks, you can chew up the gigabytes pretty quickly if you want to save a frame every 0.1 second on a 30 minutes movie.

Points of Interest

The "Save" button saves the current frame to a JPEG file in the "tmp" subdirectory. The "Scan" button loops through the whole movie and saves a frame every second (or 0.1 second).

The MediaDetClass as imported with Visual Studio is not a Windows control, its base class is System.Object, and it seems that after calling the method WriteBitmapBits, a handle to the bitmap file just created stays open. Therefore, the application, sometimes, complains that a file is already being used. I have just increased a variable counter to avoid most of these situations; an alternative solution would have been to wrap the MediaDetClass a second time in a more sophisticated implementation.

As mentioned, this is not an ideal solution. DirectShow is not going to appear in a managed version (as opposed to the rest of the DirectX API). I imagine it is for performance reasons. But as this application shows, an interop version will do the job; as they say "It Just Works!", which is fine for many situations.

I have included a file ("build.cmd" ) with the command line needed to compile the application in a shell window where the C# compiler must be found on the path.

Limitations and known issues

The application extracts a frame every second, by default. Under the Options menu, you can choose to extract a frame every one tenth of a second. This is only taken in consideration when you press the "Scan" button.

The application only saves a bitmap with the resolution 320 x 240. And they are saved in the "tmp" subdirectory (that will be created when you run the application).

The application is meant to extract pictures from movie files and is a poor application for viewing movies. The creation of new instances of the MediaDetClass type makes this restriction unavoidable.

I have created a thread to be able to keep track of the progress so far (which is displayed on a static label) when scanning a whole movie. The thread only updates the label.

The length of the movie is immediately overwritten when opening a second movie with the current position.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

Share

About the Author

daniel049
United States United States
You can read my blog entries at:
http://wwww.informikon.com/blog/

You may also be interested in...

Comments and Discussions

 
QuestionI can not get this to work! Help! Daniel049 Solution looks good but won't work for me! Pin
mplaskow27-Jul-15 7:06
membermplaskow27-Jul-15 7:06 
GeneralMy vote of 1 Pin
majid torfi1-Sep-14 5:02
membermajid torfi1-Sep-14 5:02 
BugThe video file mpg file format error Pin
Member 1060739318-Feb-14 16:35
memberMember 1060739318-Feb-14 16:35 
Questioncouldn't open file Pin
Member 98291972-Feb-14 20:49
memberMember 98291972-Feb-14 20:49 
Questionhow to get Frame Timestamp? Pin
Pdeveloper19-Aug-13 23:31
memberPdeveloper19-Aug-13 23:31 
QuestionMP4 format file not working Pin
Sabyasachi Maity16-May-13 4:19
memberSabyasachi Maity16-May-13 4:19 
Questionvery nice and helpful article Pin
ahmed_saber96316-Jul-12 21:05
memberahmed_saber96316-Jul-12 21:05 
QuestionI have a mistake Pin
drewwestlhq16-May-12 0:00
memberdrewwestlhq16-May-12 0:00 
AnswerRe: I have a question Pin
saad32412-Mar-13 20:37
membersaad32412-Mar-13 20:37 
QuestionPossible to extract from MKV file? Pin
babzog25-Apr-12 6:40
memberbabzog25-Apr-12 6:40 
Question"Couldn't open File" error for some AVI files Pin
shashi_kant17-Feb-11 14:08
membershashi_kant17-Feb-11 14:08 
GeneralExtracting frames from .mov files Pin
Marek_bd730-Nov-08 3:56
memberMarek_bd730-Nov-08 3:56 
GeneralRe: Extracting frames from .mov files Pin
Marek_bd76-Dec-08 22:08
memberMarek_bd76-Dec-08 22:08 
GeneralRe: Extracting frames from .mov files Pin
naveedesahar2-Jul-13 23:37
membernaveedesahar2-Jul-13 23:37 
GeneralRe: Extracting frames from .mov files Pin
naveedesahar26-Feb-14 3:25
membernaveedesahar26-Feb-14 3:25 
Generalcan't change browsing interval to 0.1 Pin
kuchiki_itachi20-Nov-08 3:51
memberkuchiki_itachi20-Nov-08 3:51 
GeneralThank you Daniel. Mixed results: HRESULT: 0x80040200 Pin
David Wyn Evans23-Dec-07 9:17
memberDavid Wyn Evans23-Dec-07 9:17 
GeneralRe: Thank you Daniel. Mixed results: HRESULT: 0x80040200 Pin
David Wyn Evans23-Dec-07 11:03
memberDavid Wyn Evans23-Dec-07 11:03 
Questionwhy u show a video frame in the picture box every second? Pin
cebong17-Dec-07 4:45
membercebong17-Dec-07 4:45 
GeneralTransform Filter Pin
karl alexander2-Nov-07 22:23
memberkarl alexander2-Nov-07 22:23 
GeneralRe: Transform Filter Pin
daniel0493-Nov-07 2:46
memberdaniel0493-Nov-07 2:46 
GeneralThis code sucks... Pin
ztrqwzeuztewuzqtwueztr16-Oct-07 17:47
memberztrqwzeuztewuzqtwueztr16-Oct-07 17:47 
GeneralRe: This code sucks... Pin
Andreas04916-Oct-07 23:10
memberAndreas04916-Oct-07 23:10 
GeneralRe: This code sucks... Pin
jambonbill8-Oct-09 0:19
memberjambonbill8-Oct-09 0:19 
Generalleaves file open Pin
phillkalksjf23-Sep-07 10:56
memberphillkalksjf23-Sep-07 10:56 
GeneralRe: leaves file open Pin
daniel04925-Sep-07 7:19
memberdaniel04925-Sep-07 7:19 
GeneralRe: leaves file open Pin
daniel04926-Sep-07 3:13
memberdaniel04926-Sep-07 3:13 
GeneralRe: leaves file open Pin
cslxxwilliam23-Feb-10 22:49
membercslxxwilliam23-Feb-10 22:49 
GeneralLabel On This Screen Pin
karl alexander23-Sep-07 6:56
memberkarl alexander23-Sep-07 6:56 
GeneralRe: Label On This Screen Pin
daniel04925-Sep-07 7:06
memberdaniel04925-Sep-07 7:06 
GeneralRe: Label On This Screen Pin
karl alexander26-Sep-07 8:43
memberkarl alexander26-Sep-07 8:43 
GeneralGreat work. Useful for AI research. Pin
Jim Carnicelli20-Sep-07 8:46
memberJim Carnicelli20-Sep-07 8:46 
GeneralRe: Great work. Useful for AI research. Pin
daniel04922-Sep-07 6:14
memberdaniel04922-Sep-07 6:14 
GeneralRe: Great work. Useful for AI research. Pin
cslxxwilliam23-Feb-10 22:49
membercslxxwilliam23-Feb-10 22:49 
GeneralExcellent work Pin
Nishant Sivakumar27-Aug-07 15:28
mvpNishant Sivakumar27-Aug-07 15:28 
General"Logon failure: unknown user name or bad password" Pin
MIke Gorgone14-Jun-07 4:00
memberMIke Gorgone14-Jun-07 4:00 
GeneralQUICK UPDATE Pin
MIke Gorgone14-Jun-07 7:09
memberMIke Gorgone14-Jun-07 7:09 
GeneralRe: "Logon failure: unknown user name or bad password" Pin
Member 366472112-May-10 17:38
memberMember 366472112-May-10 17:38 
QuestionCapture a Single Frame and search the same one from a *.mpg? Pin
999ny99928-May-07 13:39
member999ny99928-May-07 13:39 
GeneralException from HRESULT: 0x80040217 Pin
Khunglongbeo20-May-07 21:10
memberKhunglongbeo20-May-07 21:10 
GeneralRe: Exception from HRESULT: 0x80040217 Pin
daniel04921-May-07 3:21
memberdaniel04921-May-07 3:21 
GeneralRe: Exception from HRESULT: 0x80040217 Pin
Khunglongbeo21-May-07 19:06
memberKhunglongbeo21-May-07 19:06 
GeneralRe: Exception from HRESULT: 0x80040217 Pin
Khunglongbeo21-May-07 21:26
memberKhunglongbeo21-May-07 21:26 
GeneralRe: Exception from HRESULT: 0x80040217 Pin
daniel04924-May-07 8:37
memberdaniel04924-May-07 8:37 
GeneralRe: Exception from HRESULT: 0x80040217 Pin
RobyNova19-Dec-07 3:50
memberRobyNova19-Dec-07 3:50 
GeneralExtracting still pictures from movie files Pin
nir golan19-Apr-07 3:44
membernir golan19-Apr-07 3:44 
Generalvideo compression Pin
Member #382314321-Mar-07 19:59
memberMember #382314321-Mar-07 19:59 
GeneralRe: video compression Pin
daniel04929-Mar-07 3:34
memberdaniel04929-Mar-07 3:34 
QuestionGetting the number of frames in the video Pin
mary ann19-Mar-07 1:15
membermary ann19-Mar-07 1:15 
AnswerRe: Getting the number of frames in the video Pin
daniel04919-Mar-07 13:43
memberdaniel04919-Mar-07 13:43 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.150728.1 | Last Updated 24 Feb 2005
Article Copyright 2005 by daniel049
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid