Splitting an AVI File into Multiple Bitmaps Using ltmmSampleTarget Example for Visual Basic
The following code utilizes ltmmSampleTarget and ltmmConvertCtrl to generate multiple device independent bitmaps from an AVI file.
' declarations
Private Type BITMAPINFOHEADER '40 bytes
biSize As Long
biWidth As Long
biHeight As Long
biPlanes As Integer
biBitCount As Integer
biCompression As Long
biSizeImage As Long
biXPelsPerMeter As Long
biYPelsPerMeter As Long
biClrUsed As Long
biClrImportant As Long
End Type
Private Type BITMAPFILEHEADER ' 14 bytes
' just leave off bfType, it messes up the alignment
' bfType As Integer
bfSize As Long ' 12 bytes from here
bfReserved1 As Integer
bfReserved2 As Integer
bfOffBits As Long
End Type
Private Type RECT ' 16 bytes
Left As Long
Top As Long
Right As Long
Bottom As Long
End Type
Private Type REFERENCE_TIME ' 8 bytes
lowpart As Long
highpart As Long
End Type
Private Type VIDEOINFOHEADER ' 88 bytes
rcSource As RECT
rcTarget As RECT
dwBitRate As Long
dwBitErrorRate As Long
AvgTimePerFrame As REFERENCE_TIME
bmiHeader As BITMAPINFOHEADER
End Type
Const FILE_SHARE_READ = &H1
Const OPEN_EXISTING = 3
Const INVALID_HANDLE_VALUE = -1
Const GENERIC_READ = &H80000000
Const GENERIC_WRITE = &H40000000
Const CREATE_ALWAYS = 2
Const FILE_ATTRIBUTE_NORMAL = &H80
Private Declare Function CreateFile Lib "kernel32" Alias "CreateFileA" (ByVal lpFileName As String, ByVal dwDesiredAccess As Long, ByVal dwShareMode As Long, ByVal lpSecurityAttributes As Long, ByVal dwCreationDisposition As Long, ByVal dwFlagsAndAttributes As Long, ByVal hTemplateFile As Long) As Long
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
Private Declare Function WriteFile Lib "kernel32" (ByVal hFile As Long, lpBuffer As Any, ByVal nNumberOfBytesToWrite As Long, lpNumberOfBytesWritten As Long, ByVal lpOverlapped As Long) As Long
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
'
' SaveBMP24
' saves a bitmap to a file (supports only 24 BPP)
' strFile - output file name
' bih - BITMAPINFOHEADER
' Bits - bitmap image data
'
Private Sub SaveBMP24(strFile As String, bih As BITMAPINFOHEADER, Bits() As Byte)
Dim hFile As Long
Dim bfh As BITMAPFILEHEADER
Dim nWritten As Long
Dim bfType As Integer
hFile = CreateFile(strFile, GENERIC_READ + GENERIC_WRITE, 0, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0)
If hFile = INVALID_HANDLE_VALUE Then
Exit Sub
End If
bfType = &H4D42
bfh.bfOffBits = 14 + bih.biSize
bfh.bfSize = bfh.bfOffBits + bih.biSizeImage
bfh.bfReserved1 = 0
bfh.bfReserved2 = 0
If (WriteFile(hFile, bfType, 2, nWritten, 0) = 0 Or nWritten <> 2) Then
CloseHandle hFile
Exit Sub
End If
If (WriteFile(hFile, bfh, 12, nWritten, 0) = 0 Or nWritten <> 12) Then
CloseHandle hFile
Exit Sub
End If
If (WriteFile(hFile, bih, bih.biSize, nWritten, 0) = 0 Or nWritten <> bih.biSize) Then
CloseHandle hFile
Exit Sub
End If
If (WriteFile(hFile, Bits(0), bih.biSizeImage, nWritten, 0) = 0 Or nWritten <> bih.biSizeImage) Then
CloseHandle hFile
Exit Sub
End If
CloseHandle hFile
End Sub
'
' Copy VideoInfoHeader
' copys an array to a video info header
' vih - destination video info header
' viharr - source array
'
Private Sub CopyVideoInfoHeader(vih As VIDEOINFOHEADER, viharr() As Byte)
CopyMemory vih, viharr(0), 88
End Sub
'
' SplitAvi
' splits an avi file into individual BMP files
' strAviFile - source file name
' strOutputDir - directory of output BMP files (split?.bmp)
' MaxFrames - maximum number of BMP files (frames) to generate
'
Sub SplitAvi(strAviFile As String, strOutputDir As String, MaxFrames As Integer)
Dim SampleTarget As ltmmSampleTarget
Dim MediaType As ltmmMediaType
Dim MediaSample As ltmmMediaSample
Dim strFile As String
Dim n As Integer
Dim vih As VIDEOINFOHEADER
' create sample target
Set SampleTarget = New ltmmSampleTarget
' create the media type object
Set MediaType = New ltmmMediaType
' set type to MEDIATYPE_Video
MediaType.Type = "{73646976-0000-0010-8000-00AA00389B71}"
' set subtype to MEDIASUBTYPE_RGB24
MediaType.Subtype = "{e436eb7d-524f-11ce-9f53-0020af0ba770}"
' set the accepted media type
SampleTarget.SetAcceptedMediaType MediaType
' get it back for debugging
Set MediaType = SampleTarget.GetAcceptedMediaType ()
' set the convert input file name
ltmmConvertCtrl1.SourceFile = strAviFile
' set the convert object target
ltmmConvertCtrl1.TargetObject = SampleTarget
' start the conversion
ltmmConvertCtrl1.StartConvert
' get the connected media type
Set MediaType = SampleTarget.GetConnectedMediaType ()
' get the VIDEOINFOHEADER
CopyVideoInfoHeader vih, MediaType.Format
For n = 0 To (MaxFrames - 1)
' fetch a sample
On Error GoTo Done
Set MediaSample = SampleTarget.GetSample (1000)
' save the image
strFile = strOutputDir & "split" & CStr(n + 1) & ".bmp"
SaveBMP24 strFile, vih.bmiHeader, MediaSample.Buffer
Set MediaSample = Nothing
Next
Done:
' stop
ltmmConvertCtrl1.StopConvert
End Sub
Private Sub Form_Load()
SplitAvi "c:\count.avi", "c:\", 10
End Sub