|Bitmaps to videos|
|Written by Harry Fairhead|
|Tuesday, 21 July 2009|
Page 3 of 5
Making the video
Now we have a bitmap class we can move on to make use of it within a BmpToAVI class.
Add a new class called BmpToAVI to the project. The new class is going to make use of a number of API calls within the VfW API but rather than translate them all it makes more sense to create definitions for only those that are needed.
When you use VfW you first have to initialise the system and when you have finished you have to free it. These are most sensibly done in the class constructor and destructor as these are called automatically when the class is created and destroyed respectively:
public BmpToAVI(IntPtr hwnd)
The need for the hwnd parameter will become apparent later. For now we simply store it in a private variable:
private IntPtr m_hWnd;
The API definitions are the first of several and they simply define the DLL in which the functions reside. Things get more complicated when we have parameters to translate to C# data types. To make these DllImport commands work we also need to add:
The VfW AVI system works in terms of multimedia data streams stored in a single file. Streams can be video, audio or text. First we have to open, and in this case create, an AVI file and this can be done as part of adding the first bitmap to the video.
Add the following function to the class:
public void FirstFrame(
This returns a pointer to the AVI file that is used in other API calls and this has to be declared as a private global variable along with the other pointers to the streams that we are going to create – one standard and one compressed:
private IntPtr pFile = IntPtr.Zero;
The definition of the API call is:
and the constants are:
private const int OF_WRITE=0x00000001;
The values for constants and error codes can be found in the file VFW.h file contained in the platform SDK which can be downloaded from the Microsoft website. The translation of the DLL function is relatively easy. The IntPtr type is useful for almost any 32-bit handle or pointer. The result returned should be zero if the function has worked.
Now that we have the file open we have to create a video stream to store in it. This requires us to provide information about the format of the video. Not difficult but the API does seem to need this or very similar information supplied to it more often than seems strictly necessary. Much if the format information is concerned with the details of the bitmaps that are going to be used to create the stream so now is a good time to load the first bitmap:
RawBitmap bm = new RawBitmap();
Next we need to fill in the details in an AVISTREAMINFO struct. This is fairly easy to translate from the C++ definition:
The only complication is the need to use a fixed sized character array. This is considered “unsafe” – hence you have to remember to allow unsafe code in the project properties. We also need an AVI_RECT structure. Filling in the details is fairly easy but it is difficult knowing which parameters are important and which aren’t:
AVISTREAMINFO Sinfo =
It is clear that we do need to specify the type of the stream “vids” for video in this case, the size of the frame and the frame rate, set to 10 frames per second in this case. We also need the mmioStringToFOURCC to convert the string “vids” to the multimedia code for a video stream:
[DllImport("winmm.dll", EntryPoint =
In this case we use an EntryPoint to specify the function in the DLL because it has a slightly different name to the C# function.
The stream can now be created using the format information:
result = AVIFileCreateStream(
This returns a pointer to the video stream within the AVI file. The definition of the API call is:
|Last Updated ( Tuesday, 21 July 2009 )|