Introduction

A simple VB.Net application that combines a folder full of JPG images into an AVI video file. The source project is a complete Windows Forms application that allows for immediate use of the program as intended. 

My specific requirement was to capture web cam images at regular intervals and then automate the creation of a video on a daily basis. The individual images were displayed on an ASPX web page (updated every minute), and the nightly build of all the images into a video meant that a whole days activities could be reviewed with ease in Windows Media Player. 

(Note: the automation aspect is not included in the source project; but that's something you can easily add for yourself if required.) 

Other Code 

The code relies upon a C# compiled "AVI_Capture.Dll". The source for that DLL can be found here;

http://www.adp-gmbh.ch/csharp/avi/write_avi.html 

All due credit to the author of that code; without which this article would not be possible.

Making the DLL  

The C# code will not covert readily to VB, so install Visual C# Express and prepare to compile it. You will discover 2 Errors. To fix them, uncomment the two //new IntPtr(0); so that the errors go away. So you're left with...  

opts.lpFormat = new IntPtr(0); 

... 

opts.lpParms = new IntPtr(0); 

Now use the DLL as follows... 

1. Open up VisualBasic.Net (Express or otherwise).

2. Create a Windows Forms project (as an example).

3. Add a Reference to the DLL you just created. 

Using the code  

The form has some simple variables, and just one Imports statement. 

       Imports system.io 
 	'integers
    	Dim iFRAME_RATE As Integer = 10 'output video frames per second
    	Dim iFRAME_COUNT As Integer = 0 'will be used to iterate the images available
    	Dim iFRAME_WIDTH As Integer = 640 'default video output pixel width
    	Dim iFRAME_HEIGHT As Integer = 480 'default video output pixel height
    	Dim iINDEX As Integer = 0 'used as the image process indexer

    	'booleans
    	Dim bRotateImage As Boolean = False 'images seem to need rotated thru 180 by default
  
    	'strings
    	Dim strImageFileName As String = ""
    	Dim strImageSourceFolder As String = ""
    	Dim strVideoFileName As String = ""
    	Dim strVideoDestFolder As String = ""

The following code is fired by the [MakeAVI] button on the form. (Note some code has been removed for clarity; but will be found in the source files, again all commented.) 

Essentially we iterate a folder that contains our images, we then load them into an Image object, we manipulate the image as required, then we copy in into another Image object that has been associated with the AVI video stream. After that it's a matter of adding each new image as a frame to the video.  

	Private Sub btnMakeAVI_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnMakeAVI.Click

        'main routine to create the AVI from the group of images found in the source folder
    
 	'make sure we have some images to process
        Dim imageArray As Array = GetImageArray()
        If imageArray Is Nothing Then Exit Sub

        'zero based index, so minus 1
        iFRAME_COUNT = imageArray.Length - 1
        'if we have no images, then we have no point
        If iFRAME_COUNT = 0 Then Exit Sub

        'establish settings
        Dim fr As UInt32 'set up a uint32 for frame rate
        iFRAME_RATE = CInt(rateComboBox.Text)
        If iFRAME_RATE < 5 Or iFRAME_RATE > 30 Then iFRAME_RATE = 10
        fr = Convert.ToUInt32(iFRAME_RATE)

	'setup the progress bar (optional, my form hangs with "Program Not Responding", see code below to avoid this
        progressBar.Minimum = 0
        progressBar.Maximum = iFRAME_COUNT

	'create instance of our video encoder
        Dim AW As AviWriter = New AviWriter 'this is the DLL you just referenced
        'need to attach it to a bitmap
        Dim BM As Bitmap
        'use some integers to format the Width and Height, eg 640 and 480
        BM = AW.Open(videoFile, fr, iFRAME_WIDTH, iFRAME_HEIGHT) 
        'with a graphics surface attached to it we could add text and graphics if required to each frame
        Dim canvas As Graphics = Graphics.FromImage(BM)

	'main loop to build the avi from the images
        Try
            'generate the video file...
            For iINDEX = 0 To iFRAME_COUNT 'loop through writing each frame one at a time, 
		'iFRAME_COUNT must equal the number of images in your folder - 1 
                'if you want to super-impose some text or graphics use the canvas object
                canvas.Clear(Color.White) 'clear the canvas of any previous content
                'get the next image from disc, where strImageSourceFolder points to your fully qualified images folder
                Dim imageFile As Image = Image.FromFile(strImageSourceFolder & "\" & getNextImage(iINDEX, imageArray))
                'if we need to rotate then do that now, my images were upside down, so added this feature
                If bRotateImage = True Then
                    imageFile.RotateFlip(RotateFlipType.Rotate180FlipNone)
                End If
                'we need to potentially resize the source image if the video output resolution is different
                'passing iFRAME_WIDTH, iFRAME_HEIGHT to canvas.Drawimage effects a re-size for us
                'now render the image into our graphics object
                canvas.DrawImage(imageFile, 0, 0, iFRAME_WIDTH, iFRAME_HEIGHT)
                'if you want to add text or graphics to the canvas, do that here
                'e.g. canvas.DrawEllipse(Pens.Blue, new Rectangle(1,1,639, 479)), etc
                '
                'finally add the next frame to our video
                AW.AddFrame() 'add the bitmap (BM) to the AVI file
                'update the progress bar (my form has a progress bar, this is optional)
                progressBar.PerformStep()
                'buy the form some time to update the progress bar
                'and rid us of "program not responding" in title bar =)
                System.Threading.Thread.Sleep(5)
                Application.DoEvents()
            Next
            'all done, close the video off to disc
            AW.Close()
        Catch ex As Exception
            'emergency, close the video off to disc to be sure
            AW.Close()
        End Try

 	'reset the progress bar
        progressBar.Value = 0

    	End Sub	
		 

The form permits setting of both the frame rate and the video resolution. Included in the code above is a section that automatically rescales the source images to fit the required resolution. 

               canvas.DrawImage(imageFile, 0, 0, iFRAME_WIDTH, iFRAME_HEIGHT) 

There are a few helper functions included in the project for example to return an array of file names from the source images folder. Also the user settings are stored using the My.Settings feature. The Canvas object was included for reference, although it's not actually been tested! 

Points of Interest

Interestingly, when the AVI dll is invoked you actually get presented with a dialogue box prompting you to select the required codec to use. A 640 x 480 Uncompressed file may run to 300Mb, however another codec may produce a 20Mb video from the same source. 

推荐.NET配套的通用数据层ORM框架:CYQ.Data 通用数据层框架