Windows has two API to handle AVI files: an old API named “Video For Windows” (VfW) and a new API named “DirectShow”. The old API is the easiest to use for the task.
A guy named Gopalakrishna Palemat wrote a Visual Studio C++ application to demonstrate that use of VfW API. I have ported his code to Delphi. I have slightly updated his code to fix shortcomings and make it “the Delphi way”.
The original article can be found at http://gopalakrishna.palem.in/createmovie.html
My Delphi source code can be found at http://www.overbyte.be/eng/blog_source_Code.html
I will speak only about my source code from now.
All the AVI creation code has been moved into a component named “TAviFromBitmaps”. This class handle everything required with VfW API to create an AVI movie, compressed or not. You just has to create an instance of the class and call his AppendNewFrame method to add a bitmap at the end of the already added bitmaps. The result is an AVI file.
As a simple sample, I wrote a procedure which generate an AVI file made of 25 bitmaps generated on the fly. Each bitmap contain the text “Delphi rocks!” and the number of the frame. This is for simple demo. As I said above, you could as well produce bitmap with a 3D scene viewed from a moving point of view, or a zoom into a Mandelbrot fractal.
procedure TCAviFileForm.GenerateAvi var I : Integer; Y : Integer; H : Integer; BackBitmap : Graphics.TBitMap; Avi : TAviFromBitmaps; begin BackBitmap := Graphics.TBitMap.Create; BackBitmap.Width := 320; BackBitmap.Height := 240; BackBitmap.PixelFormat := TPixelFormat.pf32bit; Avi := TAviFromBitmaps.CreateAviFile( nil, 'output.avi', //MKFOURCC('x', 'v', 'i', 'd'),// XVID (MPEG-4) compression MKFOURCC('D', 'I', 'B', ' '), // No compression 2, 1); // 2 frames per second // First, add a blank frame Avi.AppendNewFrame(BackBitmap.Handle); // Then add frames with text BackBitmap.Canvas.Font.Size := 20; H := (BackBitmap.Canvas.TextHeight('I') * 15) div 10; Y := (BackBitmap.Height div 2) - H; BackBitmap.Canvas.TextOut(10, Y, 'Delphi rocks!'); Y := (BackBitmap.Height div 2); for I := 1 to 25 do begin BackBitmap.Canvas.TextOut(10, Y, IntToStr(I)); Avi.AppendNewFrame(BackBitmap.Handle); end; // Finally, add two blank frame // (MediaPlayer doesn't show the last two frames) BackBitmap.Canvas.FillRect(Rect(0, 0, BackBitmap.Width, BackBitmap.Height)); Avi.AppendNewFrame(BackBitmap.Handle); Avi.AppendNewFrame(BackBitmap.Handle); FreeAndNil(Avi); FreeAndNil(BackBitmap); end;
Compression of the AVI is very important. Without compression, your AVI file will be quickly very large. VfW API is able to compress with about any algorithm. It is enough to install a “codec” into Windows. I like the XVID codec because it produces MPEG-4 video with high quality and high compression. Xvid is an open-source research project focusing on video compression and is a collaborative development effort (http://www.xvid.org). All code is released under the terms of GNU GPL license.
To use XVID compressor, download the setup from http://www.xvid.org and install it. Microsoft Media Player is able to decode XVID compressed movie without installing xvid software because the result is a standard MPEG-4 file.
Each codec is identified by a four character code name “FourCC”. VfW API has a function to transform those four characters codes into an integer value suitable for the rest of the API. This is why you see “MKFOURCC(‘x’, ‘v’, ‘I’, ‘d’)” in the above code.
Of course compression comes with a price: image quality is not the same as the original. So in some applications, you may want to avoid compression. This is done by selecting a compressor of type “MKFOURCC(‘D’, ‘I’, ‘B’, ‘ ’)” (Fourth character is a space).
Download source code from: http://www.overbyte.be/eng/blog_source_code.html
Follow me on Twitter
Follow me on LinkedIn
Follow me on Google+
Visit my website: http://www.overbyte.be