|
-
Feb 16th, 2009, 07:37 AM
#1
Thread Starter
Addicted Member
Help converting BMP to AVI C# Code to .NET
I found some code on the net that is supposed to convert a BMP file into a AVI file.
http://www.adp-gmbh.ch/csharp/avi/write_avi.html
The example is in C# so i converted it using a C# to VB.NET converter and fixed a few of the conversion bugs. The code executes but fails on the line 'Throw New AviException("error for AVIFileOpen")' saying 'AVI exception unhandled'. Perhaps someone could fix the code or tell me what i have done wrong.
Code supplied in next post due to size restriction on forum posts:
-
Feb 16th, 2009, 07:40 AM
#2
Thread Starter
Addicted Member
Re: Help converting BMP to AVI C# Code to .NET
Code:
Imports System
Imports System.Runtime.InteropServices
Imports System.Drawing
Imports System.Drawing.Imaging
Public Class Form1
<StructLayout(LayoutKind.Sequential, Pack:=1)> _
Private Structure AVISTREAMINFOW
Public fccType, fccHandler, dwFlags, dwCaps As UInt32
Public wPriority, wLanguage As UInt16
Public dwScale, dwRate, dwStart, dwLength, dwInitialFrames, dwSuggestedBufferSize, dwQuality, dwSampleSize, rect_left, rect_top, rect_right, rect_bottom, dwEditCount, dwFormatChangeCount As UInt32
'Public szName0, szName1, ..... szName63 As UInt16
Public szName0, szName1, szName63 As UInt16
End Structure 'AVISTREAMINFOW
<StructLayout(LayoutKind.Sequential, Pack:=1)> _
Private Structure AVICOMPRESSOPTIONS
Public fccType As UInt32
Public fccHandler As UInt32
Public dwKeyFrameEvery As UInt32 ' only used with AVICOMRPESSF_KEYFRAMES
Public dwQuality As UInt32
Public dwBytesPerSecond As UInt32 ' only used with AVICOMPRESSF_DATARATE
Public dwFlags As UInt32
Public lpFormat As IntPtr
Public cbFormat As UInt32
Public lpParms As IntPtr
Public cbParms As UInt32
Public dwInterleaveEvery As UInt32
End Structure 'AVICOMPRESSOPTIONS
<StructLayout(LayoutKind.Sequential, Pack:=1)> _
Public Structure BITMAPINFOHEADER
Public biSize As UInt32
Public biWidth As Int32
Public biHeight As Int32
Public biPlanes As Int16
Public biBitCount As Int16
Public biCompression As UInt32
Public biSizeImage As UInt32
Public biXPelsPerMeter As Int32
Public biYPelsPerMeter As Int32
Public biClrUsed As UInt32
Public biClrImportant As UInt32
End Structure 'BITMAPINFOHEADER
Public Class AviException
Inherits ApplicationException
Public Sub New(ByVal s As String)
MyBase.New(s)
End Sub 'New
Public Sub New(ByVal s As String, ByVal hr As Int32)
MyBase.New(s)
If hr = AVIERR_BADPARAM Then
err_msg = "AVIERR_BADPARAM"
Else
err_msg = "unknown"
End If
End Sub 'New
Public Function ErrMsg() As String
Return err_msg
End Function 'ErrMsg
Private AVIERR_BADPARAM As Int32 = -2147205018
Private err_msg As String
End Class 'AviException
Private Const OF_WRITE As Long = &H1
Private Const OF_CREATE As Long = &H1000
Private Const OF_SHARE_DENY_NONE As Long = &H40
Private Const AVIIF_KEYFRAME As Long = &H10L
Public Function Open(ByVal fileName As String, ByVal frameRate As UInt32, ByVal width As Integer, ByVal height As Integer) As Bitmap
frameRate_ = frameRate
width_ = width
height_ = height
bmp_ = New Bitmap(width, height, PixelFormat.Format24bppRgb)
Dim bmpDat As BitmapData = bmp_.LockBits(New Rectangle(0, 0, width, height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb)
stride_ = bmpDat.Stride
bmp_.UnlockBits(bmpDat)
AVIFileInit()
Dim hr As Integer = AVIFileOpen(pfile_, fileName, OF_CREATE Or OF_WRITE Or OF_SHARE_DENY_NONE, 0)
If hr <> 0 Then
Throw New AviException("error for AVIFileOpen")
End If
CreateStream()
SetOptions()
Return bmp_
End Function 'Open
Public Sub AddFrame()
Dim bmpDat As BitmapData = bmp_.LockBits(New Rectangle(0, 0, CInt(width_), CInt(height_)), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb)
Dim hr As Integer = AVIStreamWrite(psCompressed_, count_, 1, bmpDat.Scan0, CType(stride_ * height_, Int32), 0, 0, 0)
If hr <> 0 Then
Throw New AviException("AVIStreamWrite")
End If
bmp_.UnlockBits(bmpDat)
count_ += 1
End Sub 'AddFrame
Public Sub Close()
AVIStreamRelease(ps_)
AVIStreamRelease(psCompressed_)
AVIFileRelease(pfile_)
AVIFileExit()
End Sub 'Close
Private Sub CreateStream()
Dim strhdr As New AVISTREAMINFOW
strhdr.fccType = fccType_
strhdr.fccHandler = fccHandler_
strhdr.dwFlags = Convert.ToUInt32(0)
strhdr.dwCaps = Convert.ToUInt32(0)
strhdr.wPriority = Convert.ToInt16(0)
strhdr.wLanguage = Convert.ToInt16(0)
strhdr.dwScale = Convert.ToUInt32(0)
strhdr.dwRate = frameRate_ ' Frames per Second
strhdr.dwStart = Convert.ToUInt32(0)
strhdr.dwLength = Convert.ToUInt32(0)
strhdr.dwInitialFrames = Convert.ToUInt32(0)
strhdr.dwSuggestedBufferSize = Convert.ToUInt32(height_ * stride_)
strhdr.dwQuality = Convert.ToUInt32(4294967295)
strhdr.dwSampleSize = Convert.ToUInt32(0)
strhdr.rect_top = Convert.ToUInt32(0)
strhdr.rect_left = Convert.ToUInt32(0)
strhdr.rect_bottom = Convert.ToUInt32(height_)
strhdr.rect_right = Convert.ToUInt32(width_)
strhdr.dwEditCount = Convert.ToUInt32(0)
strhdr.dwFormatChangeCount = Convert.ToUInt32(0)
strhdr.szName0 = Convert.ToInt16(0)
strhdr.szName1 = Convert.ToInt16(0)
Dim hr As Integer = AVIFileCreateStream(pfile_, ps_, strhdr)
If hr <> 0 Then
Throw New AviException("AVIFileCreateStream")
End If
End Sub 'CreateStream
Private Sub SetOptions()
Dim opts As New AVICOMPRESSOPTIONS
opts.fccType = Convert.ToInt32(0) 'fccType_;
opts.fccHandler = Convert.ToInt32(0) 'fccHandler_;
opts.dwKeyFrameEvery = Convert.ToInt32(0)
opts.dwQuality = Convert.ToInt32(0) ' 0 .. 10000
opts.dwFlags = Convert.ToInt32(0) ' AVICOMRPESSF_KEYFRAMES = 4
opts.dwBytesPerSecond = Convert.ToInt32(0)
opts.lpFormat = New IntPtr(0)
opts.cbFormat = Convert.ToInt32(0)
opts.lpParms = New IntPtr(0)
opts.cbParms = Convert.ToInt32(0)
opts.dwInterleaveEvery = Convert.ToInt32(0)
Dim p As AVICOMPRESSOPTIONS
Dim pp As AVICOMPRESSOPTIONS
Dim x As IntPtr = ps_
Dim ptr_ps As IntPtr
AVISaveOptions(0, Convert.ToInt32(0), 1, ptr_ps, pp)
Dim hr As Integer = AVIMakeCompressedStream(psCompressed_, ps_, opts, 0)
If hr <> 0 Then
Throw New AviException("AVIMakeCompressedStream")
End If
Dim bi As New BITMAPINFOHEADER
bi.biSize = Convert.ToInt32(40)
bi.biWidth = Convert.ToDecimal(width_)
bi.biHeight = Convert.ToDecimal(height_)
bi.biPlanes = 1
bi.biBitCount = 24
bi.biCompression = Convert.ToInt32(0) ' 0 = BI_RGB
bi.biSizeImage = Convert.ToInt32(stride_ * height_)
bi.biXPelsPerMeter = 0
bi.biYPelsPerMeter = 0
bi.biClrUsed = Convert.ToInt32(0)
bi.biClrImportant = Convert.ToInt32(0)
hr = AVIStreamSetFormat(psCompressed_, 0, bi, 40)
If hr <> 0 Then
Throw New AviException("AVIStreamSetFormat", hr)
End If
End Sub 'SetOptions
Private Declare Sub AVIFileInit Lib "avifil32.dll" ()
Private Declare Sub AVIFileExit Lib "avifil32.dll" ()
Private Declare Function AVIFileOpen Lib "avifil32.dll" _
(ByRef ptr_pfile As Integer, ByVal fileName As String, _
ByVal flags As Integer, ByRef dummy As Integer) As Integer 'byval
Private Declare Function AVIFileOpenW Lib "avifil32.dll" _
(ByRef ptr_pfile As Integer, ByVal fileName As String, _
ByVal flags As Integer, ByRef dummy As Integer) As Integer 'byval
Private Declare Function AVIFileCreateStream Lib "avifil32.dll" _
(ByVal ptr_pfile As Integer, ByRef ptr_ptr_avi As IntPtr, _
ByRef ptr_streaminfo As AVISTREAMINFOW) As Long
Private Declare Function AVIMakeCompressedStream Lib "avifil32.dll" _
(ByRef ppsCompressed As IntPtr, ByVal aviStream As IntPtr, _
ByRef ao As AVICOMPRESSOPTIONS, ByVal dummy As Integer) As Integer
Private Declare Function AVIStreamSetFormat Lib "avifil32.dll" _
(ByVal aviStream As IntPtr, ByVal lPos As Int32, _
ByRef lpFormat As BITMAPINFOHEADER, ByVal cbFormat As Int32) As Integer
Private Declare Function AVISaveOptions Lib "avifil32.dll" _
(ByVal hwnd As Integer, ByVal flags As UInt32, _
ByVal nStreams As Integer, _
ByRef ptr_ptr_avi As IntPtr, ByRef ao As AVICOMPRESSOPTIONS) As Integer 'byval
Private Declare Function AVIStreamWrite Lib "avifil32.dll" _
(ByVal aviStream As IntPtr, ByVal lStart As Int32, _
ByVal lSamples As Int32, ByVal lpBuffer As IntPtr, _
ByVal cbBuffer As Int32, ByVal dwFlags As Int32, _
ByRef dummy1 As Int32, ByRef dummy2 As Int32) As Integer 'byval
Private Declare Function AVIStreamRelease Lib "avifil32.dll" _
(ByVal aviStream As IntPtr) As Integer
Private Declare Function AVIFileRelease Lib "avifil32.dll" _
(ByVal pfile As Integer) As Integer
Private pfile_ As Integer = 0
Private ps_ As New IntPtr(0)
Private psCompressed_ As New IntPtr(0)
Private frameRate_ As UInt32 = Convert.ToInt32(0)
Private count_ As Integer = 0
Private width_ As Integer = 0
Private stride_ As Integer = 0
Private height_ As Integer = 0
Private fccType_ As UInt32 = Convert.ToInt32(1935960438) ' vids
Private fccHandler_ As UInt32 = Convert.ToInt32(808810089) ' IV50
'1145656899; // CVID
Private bmp_ As Bitmap
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Open("C:\Image1.bmp", 25, 320, 240)
End Sub
End Class
-
Feb 16th, 2009, 09:20 AM
#3
Re: Help converting BMP to AVI C# Code to .NET
That code is doing precisely what it is supposed to. It is throwing an AviException which you have not handled. This is an example of bubbling up. Essentially, if you wrapped the above code in a class called Converter, you would then probably call it's function like this:
Code:
Dim bm As Bitmap
Using cv As New Converter()
bm = cv.Open("C:\test.avi", 54, 200, 200)
End Using
But sometimes things go wrong and the function Open throws an exception. By throwing the exception, the method is increasing flexibility by allowing you as the programmer to choose how you want to handle that exception. Which you would so something like this:
Code:
Dim bm As Bitmap
Using cv As New Converter()
Try
bm = cv.Open("C:\test.avi", 54, 200, 200)
Catch (avie As AviException)
MessageBox.Show(avie.ErrMsg)
End Try
End Using
By using a try-catch, we are handling the potential error and we can choose what we want to do. I've decided to pop up a messagebox with the error message.
As for your particular situation, your hr variable is obviously not returning 0. I think it's trying to open the file exclusively and failing.
-
Feb 16th, 2009, 09:38 AM
#4
Thread Starter
Addicted Member
Re: Help converting BMP to AVI C# Code to .NET
Thanks for your help
As the code wasnt developed by me and ive never seen it working im a little confused how this code is supposed to operate. Its not obvious to me which part of the program requires me to point it to a .bmp image for eg. Also where in the code does it specify where the finished .avi file will be saved. I have followed the code through but as i dont understand many of these statements im finding it hard to work out whats going on in the code. This is generally why i avoid doing conversions from VB6 / C# whenever possible as it rarely works.
Any help getting the above code to do something would be greatly appreciated
-
Jul 11th, 2009, 09:00 AM
#5
New Member
Re: Help converting BMP to AVI C# Code to .NET
 Originally Posted by appolospb
Thanks for your help
As the code wasnt developed by me and ive never seen it working im a little confused how this code is supposed to operate. Its not obvious to me which part of the program requires me to point it to a .bmp image for eg. Also where in the code does it specify where the finished .avi file will be saved. I have followed the code through but as i dont understand many of these statements im finding it hard to work out whats going on in the code. This is generally why i avoid doing conversions from VB6 / C# whenever possible as it rarely works.
Any help getting the above code to do something would be greatly appreciated
One of the reason you are getting an error is because this code is trying to open an AVI file without a path to the file. You will need to create an AVI File First then you can add BMP files to it.
I have posted an example of how to read AVI file information, you can use it as an example of what happens while opening your file and how to pass information to your AVIstream function. The code is located on ess-image.com
I hope this helps you out
-
Jul 13th, 2009, 04:20 AM
#6
Thread Starter
Addicted Member
Re: Help converting BMP to AVI C# Code to .NET
Thanks , ill take a look at it sometime in the next couple of days. In the meantime i went down the Windows Media Encoder SDK route and that didnt work out as had hoped. So i am definitely intrested in other methods of outputting video to avi such as this thread details.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|