Eli haluaisin tehdä kansiossa olevista kuvista .avi videon yhdistämällä kuvat jolloin fps nopeudella jonka voi itse valita. Mikäs olisi helpoin tapa toteuttaa tämä
Höh. Ton VB .NET ohjelman sisällä. Ilman mitään ulkoisia ohjelmia
Moro ShortPhp!
Tässä VB.NET'lle sovitettu ja kevennetty väännös Corinna John'in kirjoittamasta C# AviFile Wrapperista... alkuperäinen wrapperi löytyy täältä & sisältää kaikki hienoudet
VB.NET Projekti - AviAPI.dll
' AudioStream.vb Imports System Imports System.IO Imports System.Runtime.InteropServices Public Class AudioStream Inherits AviStream Public ReadOnly Property CountBitsPerSample() As Integer Get Return waveFormat.wBitsPerSample End Get End Property Public ReadOnly Property CountSamplesPerSecond() As Integer Get Return waveFormat.nSamplesPerSec End Get End Property Public ReadOnly Property CountChannels() As Integer Get Return waveFormat.nChannels End Get End Property Private waveFormat As New Avi.PCMWAVEFORMAT() Public Sub New(ByVal aviFile As Integer, ByVal aviStream As IntPtr) Me.aviFile = aviFile Me.aviStream = aviStream Dim size As Integer = Marshal.SizeOf(waveFormat) Avi.AVIStreamReadFormat(aviStream, 0, waveFormat, size) Dim streamInfo As Avi.STREAMINFO = GetStreamInfo(aviStream) End Sub Private Function GetStreamInfo( _ ByVal aviStream As IntPtr) As Avi.STREAMINFO Dim streamInfo As New Avi.STREAMINFO() Dim result As Integer = Avi.AVIStreamInfo( _ aviStream, streamInfo, Marshal.SizeOf(streamInfo)) If result <> 0 Then Throw New Exception("Exception in AVIStreamInfo: " _ + result.ToString()) End If Return streamInfo End Function Public Function GetStreamInfo() As Avi.STREAMINFO If writeCompressed Then Return GetStreamInfo(compressedStream) Else Return GetStreamInfo(aviStream) End If End Function Public Function GetFormat() As Avi.PCMWAVEFORMAT Dim format As New Avi.PCMWAVEFORMAT() Dim size As Integer = Marshal.SizeOf(format) Dim result As Integer = _ Avi.AVIStreamReadFormat( _ aviStream, 0, format, size) Return format End Function Public Function GetStreamData(ByRef streamInfo As Avi.STREAMINFO, _ ByRef format As Avi.PCMWAVEFORMAT, ByRef streamLength As Integer) As IntPtr streamInfo = GetStreamInfo() format = GetFormat() streamLength = Avi.AVIStreamLength( _ aviStream.ToInt32()) * streamInfo.dwSampleSize Dim waveData As IntPtr = Marshal.AllocHGlobal(streamLength) Dim result As Integer = Avi.AVIStreamRead(aviStream, 0, _ streamLength, waveData, streamLength, 0, _ 0) If result <> 0 Then Throw New Exception("Exception in AVIStreamRead: " _ + result.ToString()) End If Return waveData End Function Public Overloads Overrides Sub ExportStream(ByVal fileName As String) Dim opts As New Avi.AVICOMPRESSOPTIONS_CLASS() opts.fccType = CType(Avi.mmioStringToFOURCC("auds", 0), UInt32) opts.fccHandler = CType(Avi.mmioStringToFOURCC("CAUD", 0), UInt32) opts.dwKeyFrameEvery = 0 opts.dwQuality = 0 opts.dwFlags = 0 opts.dwBytesPerSecond = 0 opts.lpFormat = New IntPtr(0) opts.cbFormat = 0 opts.lpParms = New IntPtr(0) opts.cbParms = 0 opts.dwInterleaveEvery = 0 Avi.AVISaveV(fileName, 0, 0, 1, aviStream, opts) End Sub End Class
' Avi.vb Imports System Imports System.Drawing Imports System.Runtime.InteropServices Imports Microsoft.VisualBasic Public Class Avi Public Shared PALETTE_SIZE As Integer = 4 * 256 Public Shared ReadOnly streamtypeVIDEO As Integer = _ mmioFOURCC("v"C, "i"C, "d"C, "s"C) Public Shared ReadOnly streamtypeAUDIO As Integer = _ mmioFOURCC("a"C, "u"C, "d"C, "s"C) Public Shared ReadOnly streamtypeMIDI As Integer = _ mmioFOURCC("m"C, "i"C, "d"C, "s"C) Public Shared ReadOnly streamtypeTEXT As Integer = _ mmioFOURCC("t"C, "x"C, "t"C, "s"C) Public Const OF_SHARE_DENY_WRITE As Integer = 32 Public Const OF_WRITE As Integer = 1 Public Const OF_READWRITE As Integer = 2 Public Const OF_CREATE As Integer = 4096 Public Const BMP_MAGIC_COOKIE As Integer = 19778 Public Const AVICOMPRESSF_INTERLEAVE As Integer = 1 Public Const AVICOMPRESSF_DATARATE As Integer = 2 Public Const AVICOMPRESSF_KEYFRAMES As Integer = 4 Public Const AVICOMPRESSF_VALID As Integer = 8 Public Const AVIIF_KEYFRAME As Integer = 16 Public Const ICMF_CHOOSE_KEYFRAME As UInt32 = 1 Public Const ICMF_CHOOSE_DATARATE As UInt32 = 2 Public Const ICMF_CHOOSE_PREVIEW As UInt32 = 4 Public Shared Function mmioFOURCC(ByVal ch0 As Char, _ ByVal ch1 As Char, ByVal ch2 As Char, ByVal ch3 As Char) As Int32 Return (CType(CType(AscW(ch0), Byte), Int32) Or _ (CType(AscW(ch1), Byte) << 8) Or (CType(AscW(ch2), Byte) << 16) _ Or (CType(AscW(ch3), Byte) << 24)) End Function <StructLayout(LayoutKind.Sequential, Pack := 1)> _ Public Structure RECT Public left As UInt32 Public top As UInt32 Public right As UInt32 Public bottom As UInt32 End Structure <StructLayout(LayoutKind.Sequential, Pack := 1)> _ Public Structure BITMAPINFOHEADER Public biSize As Int32 Public biWidth As Int32 Public biHeight As Int32 Public biPlanes As Int16 Public biBitCount As Int16 Public biCompression As Int32 Public biSizeImage As Int32 Public biXPelsPerMeter As Int32 Public biYPelsPerMeter As Int32 Public biClrUsed As Int32 Public biClrImportant As Int32 End Structure <StructLayout(LayoutKind.Sequential)> _ Public Structure PCMWAVEFORMAT Public wFormatTag As Short Public nChannels As Short Public nSamplesPerSec As Integer Public nAvgBytesPerSec As Integer Public nBlockAlign As Short Public wBitsPerSample As Short Public cbSize As Short End Structure <StructLayout(LayoutKind.Sequential, Pack := 1)> _ Public Structure STREAMINFO Public fccType As Int32 Public fccHandler As Int32 Public dwFlags As Int32 Public dwCaps As Int32 Public wPriority As Int16 Public wLanguage As Int16 Public dwScale As Int32 Public dwRate As Int32 Public dwStart As Int32 Public dwLength As Int32 Public dwInitialFrames As Int32 Public dwSuggestedBufferSize As Int32 Public dwQuality As Int32 Public dwSampleSize As Int32 Public rcFrame As RECT Public dwEditCount As Int32 Public dwFormatChangeCount As Int32 <MarshalAs(UnmanagedType.ByValArray, SizeConst := 64)> _ Public szName As UInt16() End Structure <StructLayout(LayoutKind.Sequential, Pack := 1)> _ Public Structure BITMAPFILEHEADER Public bfType As Int16 Public bfSize As Int32 Public bfReserved1 As Int16 Public bfReserved2 As Int16 Public bfOffBits As Int32 End Structure <StructLayout(LayoutKind.Sequential, Pack := 1)> _ Public Structure FILEINFO Public dwMaxBytesPerSecond As Int32 Public dwFlags As Int32 Public dwCaps As Int32 Public dwStreams As Int32 Public dwSuggestedBufferSize As Int32 Public dwWidth As Int32 Public dwHeight As Int32 Public dwScale As Int32 Public dwRate As Int32 Public dwLength As Int32 Public dwEditCount As Int32 <MarshalAs(UnmanagedType.ByValArray, SizeConst := 64)> _ Public szFileType As Char() End Structure <StructLayout(LayoutKind.Sequential, Pack := 1)> _ Public Structure AVICOMPRESSOPTIONS Public fccType As UInt32 Public fccHandler As UInt32 Public dwKeyFrameEvery As UInt32 Public dwQuality As UInt32 Public dwBytesPerSecond As UInt32 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 <StructLayout(LayoutKind.Sequential, Pack := 1)> _ Public Class AVICOMPRESSOPTIONS_CLASS Public fccType As UInt32 Public fccHandler As UInt32 Public dwKeyFrameEvery As UInt32 Public dwQuality As UInt32 Public dwBytesPerSecond As UInt32 Public dwFlags As UInt32 Public lpFormat As IntPtr Public cbFormat As UInt32 Public lpParms As IntPtr Public cbParms As UInt32 Public dwInterleaveEvery As UInt32 Public Function ToStruct() As AVICOMPRESSOPTIONS Dim returnVar As New AVICOMPRESSOPTIONS() returnVar.fccType = Me.fccType returnVar.fccHandler = Me.fccHandler returnVar.dwKeyFrameEvery = Me.dwKeyFrameEvery returnVar.dwQuality = Me.dwQuality returnVar.dwBytesPerSecond = Me.dwBytesPerSecond returnVar.dwFlags = Me.dwFlags returnVar.lpFormat = Me.lpFormat returnVar.cbFormat = Me.cbFormat returnVar.lpParms = Me.lpParms returnVar.cbParms = Me.cbParms returnVar.dwInterleaveEvery = Me.dwInterleaveEvery Return returnVar End Function End Class <DllImport("avifil32.dll")> _ Public Shared Sub AVIFileInit() End Sub <DllImport("avifil32.dll", PreserveSig := True)> _ Public Shared Function AVIFileOpen(ByRef ppfile As Integer, _ ByVal szFile As String, ByVal uMode As Integer, _ ByVal pclsidHandler As Integer) As Integer End Function <DllImport("avifil32.dll")> _ Public Shared Function AVIFileGetStream(ByVal pfile As Integer, _ ByRef ppavi As IntPtr, ByVal fccType As Integer, _ ByVal lParam As Integer) As Integer End Function <DllImport("avifil32.dll", PreserveSig := True)> _ Public Shared Function AVIStreamStart(ByVal pavi As Integer) As Integer End Function <DllImport("avifil32.dll", PreserveSig := True)> _ Public Shared Function AVIStreamLength(ByVal pavi As Integer) As Integer End Function <DllImport("avifil32.dll")> _ Public Shared Function AVIStreamInfo(ByVal pAVIStream As IntPtr, _ ByRef psi As STREAMINFO, ByVal lSize As Integer) As Integer End Function <DllImport("avifil32.dll")> _ Public Shared Function AVIStreamGetFrameOpen(ByVal pAVIStream As IntPtr, _ ByRef bih As BITMAPINFOHEADER) As Integer End Function <DllImport("avifil32.dll")> _ Public Shared Function AVIStreamGetFrame(ByVal pGetFrameObj As Integer, _ ByVal lPos As Integer) As Integer End Function <DllImport("avifil32.dll")> _ Public Shared Function AVIFileCreateStream(ByVal pfile As Integer, _ ByRef ppavi As IntPtr, ByRef ptr_streaminfo As STREAMINFO) As Integer End Function <DllImport("avifil32.dll")> _ Public Shared Function CreateEditableStream(ByRef ppsEditable As IntPtr, _ ByVal psSource As IntPtr) As Integer End Function <DllImport("avifil32.dll")> _ Public Shared Function EditStreamCut(ByVal pStream As IntPtr, _ ByRef plStart As Int32, ByRef plLength As Int32, _ ByRef ppResult As IntPtr) As Integer End Function <DllImport("avifil32.dll")> _ Public Shared Function EditStreamCopy(ByVal pStream As IntPtr, _ ByRef plStart As Int32, ByRef plLength As Int32, ByRef ppResult As IntPtr) As Integer End Function <DllImport("avifil32.dll")> _ Public Shared Function EditStreamPaste(ByVal pStream As IntPtr, _ ByRef plPos As Int32, ByRef plLength As Int32, ByVal ppstream As IntPtr, _ ByVal lStart As Int32, ByVal lLength As Int32) As Integer End Function <DllImport("avifil32.dll")> _ Public Shared Function EditStreamSetInfo(ByVal pStream As IntPtr, _ ByRef lpInfo As STREAMINFO, ByVal cbInfo As Int32) As Integer End Function <DllImport("avifil32.dll")> _ Public Shared Function AVIMakeFileFromStreams(ByRef ppfile As IntPtr, _ ByVal nStreams As Integer, ByRef papStreams As IntPtr) As Integer End Function <DllImport("avifil32.dll")> _ Public Shared Function AVIStreamSetFormat(ByVal aviStream As IntPtr, _ ByVal lPos As Int32, ByRef lpFormat As BITMAPINFOHEADER, _ ByVal cbFormat As Int32) As Integer End Function <DllImport("avifil32.dll")> _ Public Shared Function AVIStreamSetFormat(ByVal aviStream As IntPtr, _ ByVal lPos As Int32, ByRef lpFormat As PCMWAVEFORMAT, _ ByVal cbFormat As Int32) As Integer End Function <DllImport("avifil32.dll")> _ Public Shared Function AVIStreamReadFormat(ByVal aviStream As IntPtr, _ ByVal lPos As Int32, ByRef lpFormat As BITMAPINFOHEADER, _ ByRef cbFormat As Int32) As Integer End Function <DllImport("avifil32.dll")> _ Public Shared Function AVIStreamReadFormat(ByVal aviStream As IntPtr, _ ByVal lPos As Int32, ByVal empty As Integer, ByRef cbFormat As Int32) As Integer End Function <DllImport("avifil32.dll")> _ Public Shared Function AVIStreamReadFormat(ByVal aviStream As IntPtr, _ ByVal lPos As Int32, ByRef lpFormat As PCMWAVEFORMAT, _ ByRef cbFormat As Int32) As Integer End Function <DllImport("avifil32.dll")> _ Public Shared Function AVIStreamWrite(ByVal aviStream As IntPtr, _ ByVal lStart As Int32, ByVal lSamples As Int32, ByVal lpBuffer As IntPtr, _ ByVal cbBuffer As Int32, ByVal dwFlags As Int32, _ ByVal dummy1 As Int32, ByVal dummy2 As Int32) As Integer End Function <DllImport("avifil32.dll")> _ Public Shared Function AVIStreamGetFrameClose( _ ByVal pGetFrameObj As Integer) As Integer End Function <DllImport("avifil32.dll")> _ Public Shared Function AVIStreamRelease(ByVal aviStream As IntPtr) As Integer End Function <DllImport("avifil32.dll")> _ Public Shared Function AVIFileRelease(ByVal pfile As Integer) As Integer End Function <DllImport("avifil32.dll")> _ Public Shared Sub AVIFileExit() End Sub <DllImport("avifil32.dll")> _ Public Shared Function AVIMakeCompressedStream(ByRef ppsCompressed As IntPtr, _ ByVal aviStream As IntPtr, ByRef ao As AVICOMPRESSOPTIONS, _ ByVal dummy As Integer) As Integer End Function <DllImport("avifil32.dll")> _ Public Shared Function AVISaveOptions(ByVal hwnd As IntPtr, _ ByVal uiFlags As UInt32, ByVal nStreams As Int32, ByRef ppavi As IntPtr, _ ByRef plpOptions As AVICOMPRESSOPTIONS_CLASS) As Boolean End Function <DllImport("avifil32.dll")> _ Public Shared Function AVISaveOptionsFree(ByVal nStreams As Integer, _ ByRef plpOptions As AVICOMPRESSOPTIONS_CLASS) As Long End Function <DllImport("avifil32.dll")> _ Public Shared Function AVIFileInfo(ByVal pfile As Integer, _ ByRef pfi As FILEINFO, ByVal lSize As Integer) As Integer End Function <DllImport("winmm.dll", EntryPoint := "mmioStringToFOURCCA")> _ Public Shared Function mmioStringToFOURCC(ByVal sz As String, _ ByVal uFlags As Integer) As Integer End Function <DllImport("avifil32.dll")> _ Public Shared Function AVIStreamRead(ByVal pavi As IntPtr, _ ByVal lStart As Int32, ByVal lSamples As Int32, ByVal lpBuffer As IntPtr, _ ByVal cbBuffer As Int32, ByVal plBytes As Int32, _ ByVal plSamples As Int32) As Integer End Function <DllImport("avifil32.dll")> _ Public Shared Function AVISaveV(ByVal szFile As String, _ ByVal empty As Int16, ByVal lpfnCallback As Int16, ByVal nStreams As Int16, _ ByRef ppavi As IntPtr, ByRef plpOptions As AVICOMPRESSOPTIONS_CLASS) As Integer End Function End Class
'AviManager.vb Imports System Imports System.IO Imports System.Collections Imports System.Drawing Imports System.Drawing.Imaging Imports System.Runtime.InteropServices Public Class AviManager Private aviFile As Integer = 0 Private streams As New ArrayList() Public Sub New(ByVal fileName As String, ByVal open As Boolean) Avi.AVIFileInit() Dim result As Integer If open Then result = Avi.AVIFileOpen(aviFile, fileName, Avi.OF_READWRITE, 0) Else result = Avi.AVIFileOpen(aviFile, fileName, Avi.OF_WRITE Or Avi.OF_CREATE, 0) End If If result <> 0 Then Throw New Exception("Exception in AVIFileOpen: " + result.ToString()) End If End Sub Private Sub New(ByVal aviFile As Integer) Me.aviFile = aviFile End Sub Public Function GetVideoStream() As VideoStream Dim aviStream As IntPtr Dim result As Integer = Avi.AVIFileGetStream(aviFile, _ aviStream, Avi.streamtypeVIDEO, 0) If result <> 0 Then Throw New Exception("Exception in AVIFileGetStream: " _ + result.ToString()) End If Dim stream As New VideoStream(aviFile, aviStream) streams.Add(stream) Return stream End Function Public Function GetWaveStream() As AudioStream Dim aviStream As IntPtr Dim result As Integer = Avi.AVIFileGetStream(aviFile, _ aviStream, Avi.streamtypeAUDIO, 0) If result <> 0 Then Throw New Exception("Exception in AVIFileGetStream: " _ + result.ToString()) End If Dim stream As New AudioStream(aviFile, aviStream) streams.Add(stream) Return stream End Function Public Function GetOpenStream(ByVal index As Integer) As VideoStream Return CType(streams(index), VideoStream) End Function Public Function AddVideoStream(ByVal isCompressed As Boolean, _ ByVal frameRate As Double, ByVal frameSize As Integer, _ ByVal width As Integer, ByVal height As Integer, _ ByVal format As PixelFormat) As VideoStream Dim stream As New VideoStream(aviFile, isCompressed, _ frameRate, frameSize, width, height, _ format) streams.Add(stream) Return stream End Function Public Function AddVideoStream(ByVal compressOptions As Avi.AVICOMPRESSOPTIONS, _ ByVal frameRate As Double, ByVal firstFrame As Bitmap) As VideoStream Dim stream As New VideoStream( _ aviFile, compressOptions, frameRate, firstFrame) streams.Add(stream) Return stream End Function Public Function AddVideoStream(ByVal isCompressed As Boolean, _ ByVal frameRate As Double, ByVal firstFrame As Bitmap) As VideoStream Dim stream As New VideoStream(aviFile, _ isCompressed, frameRate, firstFrame) streams.Add(stream) Return stream End Function Public Sub AddAudioStream(ByVal waveFileName As String, _ ByVal startAtFrameIndex As Integer) Dim audioManager As New AviManager(waveFileName, True) Dim newStream As AudioStream = audioManager.GetWaveStream() AddAudioStream(newStream, startAtFrameIndex) audioManager.Close() End Sub Private Function InsertSilence(ByVal countSilentSamples As Integer, _ ByVal waveData As IntPtr, ByVal lengthWave As Integer, _ ByRef streamInfo As Avi.STREAMINFO) As IntPtr Dim lengthSilence As Integer = countSilentSamples * streamInfo.dwSampleSize Dim silence As Byte() = New Byte(lengthSilence) {} Dim lengthNewStream As Integer = lengthSilence + lengthWave Dim newWaveData As IntPtr = Marshal.AllocHGlobal(lengthNewStream) Marshal.Copy(silence, 0, newWaveData, lengthSilence) Dim sound As Byte() = New Byte(lengthWave) {} Marshal.Copy(waveData, sound, 0, lengthWave) Dim startOfSound As New IntPtr(newWaveData.ToInt32() + lengthSilence) Marshal.Copy(sound, 0, startOfSound, lengthWave) Marshal.FreeHGlobal(newWaveData) streamInfo.dwLength = lengthNewStream Return newWaveData End Function Public Sub AddAudioStream(ByVal newStream As AudioStream, _ ByVal startAtFrameIndex As Integer) Dim streamInfo As New Avi.STREAMINFO() Dim streamFormat As New Avi.PCMWAVEFORMAT() Dim streamLength As Integer = 0 Dim rawData As IntPtr = newStream.GetStreamData(streamInfo, _ streamFormat, streamLength) Dim waveData As IntPtr = rawData If startAtFrameIndex > 0 Then Dim framesPerSecond As Double = GetVideoStream().FrameRate Dim samplesPerSecond As Double = newStream.CountSamplesPerSecond Dim startAtSecond As Double = startAtFrameIndex / framesPerSecond Dim startAtSample As Integer = _ CType((samplesPerSecond * startAtSecond), Integer) waveData = InsertSilence(startAtSample - 1, _ waveData, streamLength, streamInfo) End If Dim aviStream As IntPtr Dim result As Integer = _ Avi.AVIFileCreateStream(aviFile, aviStream, streamInfo) If result <> 0 Then Throw New Exception("Exception in AVIFileCreateStream: " + result.ToString()) End If result = Avi.AVIStreamSetFormat(aviStream, 0, _ streamFormat, Marshal.SizeOf(streamFormat)) If result <> 0 Then Throw New Exception("Exception in AVIStreamSetFormat: " _ + result.ToString()) End If result = Avi.AVIStreamWrite(aviStream, 0, _ streamLength, waveData, streamLength, Avi.AVIIF_KEYFRAME, _ 0, 0) If result <> 0 Then Throw New Exception("Exception in AVIStreamWrite: " + result.ToString()) End If result = Avi.AVIStreamRelease(aviStream) If result <> 0 Then Throw New Exception("Exception in AVIStreamRelease: " + result.ToString()) End If Marshal.FreeHGlobal(waveData) End Sub Public Sub AddAudioStream(ByVal waveData As IntPtr, _ ByVal streamInfo As Avi.STREAMINFO, ByVal streamFormat As Avi.PCMWAVEFORMAT, _ ByVal streamLength As Integer) Dim aviStream As IntPtr Dim result As Integer = _ Avi.AVIFileCreateStream(aviFile, aviStream, streamInfo) If result <> 0 Then Throw New Exception( _ "Exception in AVIFileCreateStream: " + result.ToString()) End If result = Avi.AVIStreamSetFormat(aviStream, 0, _ streamFormat, Marshal.SizeOf(streamFormat)) If result <> 0 Then Throw New Exception("Exception in AVIStreamSetFormat: " + result.ToString()) End If result = Avi.AVIStreamWrite(aviStream, 0, streamLength, _ waveData, streamLength, Avi.AVIIF_KEYFRAME, _ 0, 0) If result <> 0 Then Throw New Exception("Exception in AVIStreamWrite: " + result.ToString()) End If result = Avi.AVIStreamRelease(aviStream) If result <> 0 Then Throw New Exception("Exception in AVIStreamRelease: " + result.ToString()) End If End Sub Public Function CopyTo(ByVal newFileName As String, _ ByVal startAtSecond As Single, ByVal stopAtSecond As Single) As AviManager Dim newFile As New AviManager(newFileName, False) Try Dim videoStream As VideoStream = GetVideoStream() Dim startFrameIndex As Integer = _ CType((videoStream.FrameRate * startAtSecond), Integer) Dim stopFrameIndex As Integer = _ CType((videoStream.FrameRate * stopAtSecond), Integer) videoStream.GetFrameOpen() Dim bmp As Bitmap = videoStream.GetBitmap(startFrameIndex) Dim newStream As VideoStream = _ newFile.AddVideoStream(False, videoStream.FrameRate, bmp) Dim n As Integer = startFrameIndex + 1 While n <= stopFrameIndex bmp = videoStream.GetBitmap(n) newStream.AddFrame(bmp) System.Math.Max(System.Threading.Interlocked.Increment(n),n - 1) End While videoStream.GetFrameClose() Dim waveStream As AudioStream = GetWaveStream() Dim streamInfo As New Avi.STREAMINFO() Dim streamFormat As New Avi.PCMWAVEFORMAT() Dim streamLength As Integer = 0 Dim ptrRawData As IntPtr = _ waveStream.GetStreamData(streamInfo, streamFormat, streamLength) Dim startByteIndex As Integer = _ CType((startAtSecond * CType((waveStream.CountSamplesPerSecond _ * streamFormat.nChannels * waveStream.CountBitsPerSample), _ Single) / 8), Integer) Dim stopByteIndex As Integer = _ CType((stopAtSecond * CType((waveStream.CountSamplesPerSecond * _ streamFormat.nChannels * waveStream.CountBitsPerSample), _ Single) / 8), Integer) Dim ptrWavePart As New IntPtr(ptrRawData.ToInt32() + startByteIndex) Dim rawData As Byte() = New Byte(stopByteIndex - startByteIndex) {} Marshal.Copy(ptrWavePart, rawData, 0, rawData.Length) Marshal.FreeHGlobal(ptrRawData) streamInfo.dwLength = rawData.Length streamInfo.dwStart = 0 Dim unmanagedRawData As IntPtr = _ Marshal.AllocHGlobal(rawData.Length) Marshal.Copy(rawData, 0, unmanagedRawData, rawData.Length) newFile.AddAudioStream(unmanagedRawData, _ streamInfo, streamFormat, rawData.Length) Marshal.FreeHGlobal(unmanagedRawData) Catch ex As Exception newFile.Close() Throw ex End Try Return newFile End Function Public Sub Close() For Each stream As AviStream In streams stream.Close() Next Avi.AVIFileRelease(aviFile) Avi.AVIFileExit() End Sub Public Shared Sub MakeFileFromStream( _ ByVal fileName As String, ByVal stream As AviStream) Dim newFile As IntPtr = IntPtr.Zero Dim streamPointer As IntPtr = stream.StreamPointer Dim opts As New Avi.AVICOMPRESSOPTIONS_CLASS() opts.fccType = CType(Avi.streamtypeVIDEO, UInteger) opts.lpParms = IntPtr.Zero opts.lpFormat = IntPtr.Zero Avi.AVISaveOptions(IntPtr.Zero, _ Avi.ICMF_CHOOSE_KEYFRAME Or Avi.ICMF_CHOOSE_DATARATE, _ 1, streamPointer, opts) Avi.AVISaveOptionsFree(1, opts) Avi.AVISaveV(fileName, 0, 0, 1, streamPointer, opts) End Sub End Class
'AviStream.vb Imports System Public MustInherit Class AviStream Protected aviFile As Integer Protected aviStream As IntPtr Protected compressedStream As IntPtr Protected wCompressed As Boolean Friend ReadOnly Property FilePointer() As Integer Get Return aviFile End Get End Property Friend Overridable ReadOnly _ Property StreamPointer() As IntPtr Get Return aviStream End Get End Property Friend Property WriteCompressed() As Boolean Get Return wCompressed End Get Set(ByVal value As Boolean) wCompressed = value End Set End Property Public Overridable Sub Close() If writeCompressed Then Avi.AVIStreamRelease(compressedStream) End If Avi.AVIStreamRelease(StreamPointer) End Sub Public MustOverride Sub ExportStream( _ ByVal fileName As String) End Class
'VideoStream.vb Imports System Imports System.IO Imports System.Drawing Imports System.Drawing.Imaging Imports System.Runtime.InteropServices Imports Microsoft.VisualBasic Public Class VideoStream Inherits AviStream Private getFrameObject As Integer Private fraSize As Integer Public Property FrameSize() As Integer Get Return fraSize End Get Set (ByVal value As Integer) fraSize = value End Set End Property Friend fraRate As Double Public Property FrameRate() As Double Get Return fraRate End Get Set(ByVal value As Double) fraRate = value End Set End Property Private wdh As Integer Public Property Width() As Integer Get Return wdh End Get Set(ByVal value As Integer) wdh = value End Set End Property Private hgt As Integer Public Property Height() As Integer Get Return hgt End Get Set (ByVal value As Integer) hgt = value End Set End Property Private cntBitsPerPixel As Int16 Public Property CountBitsPerPixel() As Int16 Get Return cntBitsPerPixel End Get Set(ByVal value As Int16) cntBitsPerPixel = value End Set End Property Protected cntFrames As Integer Public Property CountFrames() As Integer Get Return cntFrames End Get Set (ByVal value As Integer) cntFrames = value End Set End Property Protected fFrame As Integer Public Property FirstFrame() As Integer Get Return fFrame End Get Set (ByVal value As Integer) fFrame = value End Set End Property Private cmpressOptions As Avi.AVICOMPRESSOPTIONS Public Property CompressOptions() As Avi.AVICOMPRESSOPTIONS Get Return cmpressOptions End Get Set(ByVal value As Avi.AVICOMPRESSOPTIONS) cmpressOptions = value End Set End Property Public ReadOnly Property StreamInfo() As Avi.STREAMINFO Get Return GetStreamInfo(aviStream) End Get End Property Public Sub New(ByVal aviFile As Integer, _ ByVal writeCompressed As Boolean, ByVal frameRate As Double, _ ByVal frameSize As Integer, ByVal width As Integer, _ ByVal height As Integer, ByVal format As PixelFormat) Me.aviFile = aviFile Me.writeCompressed = writeCompressed Me.frameRate = frameRate Me.frameSize = frameSize Me.width = width Me.height = height Me.countBitsPerPixel = ConvertPixelFormatToBitCount(format) Me.firstFrame = 0 CreateStream() End Sub Public Sub New(ByVal aviFile As Integer, _ ByVal writeCompressed As Boolean, ByVal frameRate As Double, _ ByVal firstFrame As Bitmap) Initialize(aviFile, writeCompressed, frameRate, firstFrame) CreateStream() AddFrame(firstFrame) End Sub Public Sub New(ByVal aviFile As Integer, ByVal compressOptions As Avi.AVICOMPRESSOPTIONS, ByVal frameRate As Double, ByVal firstFrame As Bitmap) Initialize(aviFile, True, frameRate, firstFrame) CreateStream(compressOptions) AddFrame(firstFrame) End Sub Public Sub New(ByVal aviFile As Integer, ByVal aviStream As IntPtr) Me.aviFile = aviFile Me.aviStream = aviStream Dim bih As New Avi.BITMAPINFOHEADER() Dim size As Integer = Marshal.SizeOf(bih) Avi.AVIStreamReadFormat(aviStream, 0, bih, size) Dim streamInfo As Avi.STREAMINFO = GetStreamInfo(aviStream) Me.frameRate = CType(streamInfo.dwRate, Single) / CType(streamInfo.dwScale, Single) Me.width = CType(streamInfo.rcFrame.right, Integer) Me.height = CType(streamInfo.rcFrame.bottom, Integer) Me.frameSize = bih.biSizeImage Me.countBitsPerPixel = bih.biBitCount Me.firstFrame = Avi.AVIStreamStart(aviStream.ToInt32()) Me.countFrames = Avi.AVIStreamLength(aviStream.ToInt32()) End Sub Friend Sub New(ByVal frameSize As Integer, _ ByVal frameRate As Double, ByVal width As Integer, _ ByVal height As Integer, ByVal countBitsPerPixel As Int16, _ ByVal countFrames As Integer, _ ByVal compressOptions As Avi.AVICOMPRESSOPTIONS, _ ByVal writeCompressed As Boolean) Me.frameSize = frameSize Me.frameRate = frameRate Me.width = width Me.height = height Me.countBitsPerPixel = countBitsPerPixel Me.countFrames = countFrames Me.compressOptions = compressOptions Me.writeCompressed = writeCompressed Me.firstFrame = 0 End Sub Private Sub Initialize(ByVal aviFile As Integer, _ ByVal writeCompressed As Boolean, ByVal frameRate As Double, _ ByVal firstFrameBitmap As Bitmap) Me.aviFile = aviFile Me.writeCompressed = writeCompressed Me.frameRate = frameRate Me.firstFrame = 0 Dim bmpData As BitmapData = _ firstFrameBitmap.LockBits(New Rectangle( _ 0, 0, firstFrameBitmap.Width, firstFrameBitmap.Height), _ ImageLockMode.[ReadOnly], firstFrameBitmap.PixelFormat) Me.frameSize = bmpData.Stride * bmpData.Height Me.width = firstFrameBitmap.Width Me.height = firstFrameBitmap.Height Me.countBitsPerPixel = _ ConvertPixelFormatToBitCount( _ firstFrameBitmap.PixelFormat) firstFrameBitmap.UnlockBits(bmpData) End Sub Private Function ConvertPixelFormatToBitCount( _ ByVal format As PixelFormat) As Int16 Dim formatName As String = format.ToString() If formatName.Substring(0, 6) <> "Format" Then Throw New Exception("Unknown pixel format: " + formatName) End If formatName = formatName.Substring(6, 2) Dim bitCount As Int16 = 0 If [Char].IsNumber(formatName(1)) Then bitCount = Int16.Parse(formatName) Else bitCount = Int16.Parse(formatName(0).ToString()) End If Return bitCount End Function Private Function ConvertBitCountToPixelFormat( _ ByVal bitCount As Integer) As PixelFormat Dim formatName As String If bitCount > 16 Then formatName = [String].Format("Format{0}bppRgb", bitCount) ElseIf bitCount = 16 Then formatName = "Format16bppRgb555" Else formatName = [String].Format("Format{0}bppIndexed", bitCount) End If Return CType([Enum].Parse(GetType(PixelFormat), formatName), PixelFormat) End Function Private Function GetStreamInfo(ByVal aviStream As IntPtr) As Avi.STREAMINFO Dim streamInfo As New Avi.STREAMINFO() Dim result As Integer = Avi.AVIStreamInfo( _ StreamPointer, streamInfo, Marshal.SizeOf(streamInfo)) If result <> 0 Then Throw New Exception("Exception in VideoStreamInfo: " _ + result.ToString()) End If Return streamInfo End Function Private Sub GetRateAndScale(ByRef frameRate As Double, _ ByRef scale As Integer) scale = 1 While frameRate <> CType(frameRate, Long) frameRate = frameRate * 10 scale *= 10 End While End Sub Private Sub CreateStreamWithoutFormat() Dim scale As Integer = 1 Dim rate As Double = frameRate GetRateAndScale(rate, scale) Dim strhdr As New Avi.STREAMINFO() strhdr.fccType = Avi.mmioStringToFOURCC("vids", 0) strhdr.fccHandler = Avi.mmioStringToFOURCC("CVID", 0) strhdr.dwFlags = 0 strhdr.dwCaps = 0 strhdr.wPriority = 0 strhdr.wLanguage = 0 strhdr.dwScale = CType(scale, Integer) strhdr.dwRate = CType(rate, Integer) strhdr.dwStart = 0 strhdr.dwLength = 0 strhdr.dwInitialFrames = 0 strhdr.dwSuggestedBufferSize = frameSize strhdr.dwQuality = -1 strhdr.dwSampleSize = 0 strhdr.rcFrame.top = 0 strhdr.rcFrame.left = 0 strhdr.rcFrame.bottom = CType(height, UInteger) strhdr.rcFrame.right = CType(width, UInteger) strhdr.dwEditCount = 0 strhdr.dwFormatChangeCount = 0 strhdr.szName = New UInt16(64) {} Dim result As Integer = _ Avi.AVIFileCreateStream(aviFile, aviStream, strhdr) If result <> 0 Then Throw New Exception("Exception in AVIFileCreateStream: " _ + result.ToString()) End If End Sub Private Sub CreateStream() CreateStreamWithoutFormat() If writeCompressed Then CreateCompressedStream() Else SetFormat(aviStream) End If End Sub Private Sub CreateStream(ByVal options As Avi.AVICOMPRESSOPTIONS) CreateStreamWithoutFormat() CreateCompressedStream(options) End Sub Private Sub CreateCompressedStream() Dim options As New Avi.AVICOMPRESSOPTIONS_CLASS() options.fccType = CType(Avi.streamtypeVIDEO, UInteger) options.lpParms = IntPtr.Zero options.lpFormat = IntPtr.Zero Avi.AVISaveOptions(IntPtr.Zero, _ Avi.ICMF_CHOOSE_KEYFRAME Or _ Avi.ICMF_CHOOSE_DATARATE, 1, aviStream, options) Avi.AVISaveOptionsFree(1, options) Me.compressOptions = options.ToStruct() Dim result As Integer = _ Avi.AVIMakeCompressedStream( _ compressedStream, aviStream, compressOptions, 0) If result <> 0 Then Throw New Exception("Exception in AVIMakeCompressedStream: " + result.ToString()) End If SetFormat(compressedStream) End Sub Private Sub CreateCompressedStream(ByVal options As Avi.AVICOMPRESSOPTIONS) Dim result As Integer = _ Avi.AVIMakeCompressedStream( _ compressedStream, aviStream, options, 0) If result <> 0 Then Throw New Exception("Exception in AVIMakeCompressedStream: " _ + result.ToString()) End If Me.compressOptions = options SetFormat(compressedStream) End Sub Public Sub AddFrame(ByVal bmp As Bitmap) bmp.RotateFlip(RotateFlipType.RotateNoneFlipY) Dim bmpDat As BitmapData = bmp.LockBits( _ New Rectangle(0, 0, bmp.Width, bmp.Height), _ ImageLockMode.[ReadOnly], bmp.PixelFormat) Dim result As Integer = Avi.AVIStreamWrite( _ IIF(writeCompressed,compressedStream,StreamPointer), _ countFrames, 1, bmpDat.Scan0, CType( _ (bmpDat.Stride * bmpDat.Height), Int32), 0, 0, 0) If result <> 0 Then Throw New Exception("Exception in VideoStreamWrite: " _ + result.ToString()) End If bmp.UnlockBits(bmpDat) System.Math.Max(System.Threading.Interlocked.Increment(countFrames),countFrames - 1) End Sub Private Sub SetFormat(ByVal aviStream As IntPtr) Dim bi As New Avi.BITMAPINFOHEADER() bi.biSize = Marshal.SizeOf(bi) bi.biWidth = width bi.biHeight = height bi.biPlanes = 1 bi.biBitCount = countBitsPerPixel bi.biSizeImage = frameSize Dim result As Integer = Avi.AVIStreamSetFormat(aviStream, 0, bi, bi.biSize) If result <> 0 Then Throw New Exception("Error in VideoStreamSetFormat: " _ + result.ToString()) End If End Sub Public Sub GetFrameOpen() Dim streamInfo As Avi.STREAMINFO = _ GetStreamInfo(StreamPointer) Dim bih As New Avi.BITMAPINFOHEADER() bih.biBitCount = countBitsPerPixel bih.biClrImportant = 0 bih.biClrUsed = 0 bih.biCompression = 0 bih.biPlanes = 1 bih.biSize = Marshal.SizeOf(bih) bih.biXPelsPerMeter = 0 bih.biYPelsPerMeter = 0 bih.biHeight = 0 bih.biWidth = 0 If bih.biBitCount > 24 Then bih.biBitCount = 32 ElseIf bih.biBitCount > 16 Then bih.biBitCount = 24 ElseIf bih.biBitCount > 8 Then bih.biBitCount = 16 ElseIf bih.biBitCount > 4 Then bih.biBitCount = 8 ElseIf bih.biBitCount > 0 Then bih.biBitCount = 4 End If getFrameObject = Avi.AVIStreamGetFrameOpen(StreamPointer, bih) If getFrameObject = 0 Then Throw New Exception("Exception in VideoStreamGetFrameOpen!") End If End Sub Public Sub ExportBitmap(ByVal position As Integer, _ ByVal dstFileName As String) Dim bmp As Bitmap = GetBitmap(position) bmp.Save(dstFileName, ImageFormat.Bmp) bmp.Dispose() End Sub Public Function GetBitmap(ByVal position As Integer) As Bitmap If position > countFrames Then Throw New Exception("Invalid frame position: " + position) End If Dim streamInfo As Avi.STREAMINFO = GetStreamInfo(StreamPointer) Dim dib As Integer = Avi.AVIStreamGetFrame( _ getFrameObject, firstFrame + position) Dim bih As New Avi.BITMAPINFOHEADER() bih = CType(Marshal.PtrToStructure(New IntPtr(dib), _ bih.[GetType]()), Avi.BITMAPINFOHEADER) If bih.biSizeImage < 1 Then Throw New Exception("Exception in VideoStreamGetFrame") End If Dim bitmapData As Byte() Dim address As Integer = dib + Marshal.SizeOf(bih) If bih.biBitCount < 16 Then bitmapData = New Byte(bih.biSizeImage + Avi.PALETTE_SIZE) {} Else bitmapData = New Byte(bih.biSizeImage) {} End If Marshal.Copy(New IntPtr(address), bitmapData, 0, bitmapData.Length) Dim bitmapInfo As Byte() = New Byte(Marshal.SizeOf(bih)) {} Dim ptr As IntPtr ptr = Marshal.AllocHGlobal(bitmapInfo.Length) Marshal.StructureToPtr(bih, ptr, False) address = ptr.ToInt32() Marshal.Copy(New IntPtr(address), bitmapInfo, 0, bitmapInfo.Length) Marshal.FreeHGlobal(ptr) Dim bfh As New Avi.BITMAPFILEHEADER() bfh.bfType = Avi.BMP_MAGIC_COOKIE bfh.bfSize = CType((55 + bih.biSizeImage), Int32) bfh.bfReserved1 = 0 bfh.bfReserved2 = 0 bfh.bfOffBits = Marshal.SizeOf(bih) + Marshal.SizeOf(bfh) If bih.biBitCount < 16 Then bfh.bfOffBits += Avi.PALETTE_SIZE End If Dim bw As New BinaryWriter(New MemoryStream()) bw.Write(bfh.bfType) bw.Write(bfh.bfSize) bw.Write(bfh.bfReserved1) bw.Write(bfh.bfReserved2) bw.Write(bfh.bfOffBits) bw.Write(bitmapInfo) bw.Write(bitmapData) Dim bmp As Bitmap = CType(Image.FromStream(bw.BaseStream), Bitmap) Dim saveableBitmap As New Bitmap(bmp.Width, bmp.Height) Dim g As Graphics = Graphics.FromImage(saveableBitmap) g.DrawImage(bmp, 0, 0) g.Dispose() bmp.Dispose() bw.Close() Return saveableBitmap End Function Public Sub GetFrameClose() If getFrameObject <> 0 Then Avi.AVIStreamGetFrameClose(getFrameObject) getFrameObject = 0 End If End Sub Public Function DecompressToNewFile(ByVal fileName As String, _ ByVal recompress As Boolean, ByRef newStream2 As VideoStream) As AviManager Dim newFile As New AviManager(fileName, False) Me.GetFrameOpen() Dim frame As Bitmap = GetBitmap(0) Dim newStream As VideoStream = _ newFile.AddVideoStream(recompress, frameRate, frame) frame.Dispose() Dim n As Integer = 1 While n < countFrames frame = GetBitmap(n) newStream.AddFrame(frame) frame.Dispose() System.Math.Max(System.Threading.Interlocked.Increment(n),n - 1) End While Me.GetFrameClose() newStream2 = newStream Return newFile End Function Public Overloads Overrides Sub ExportStream(ByVal fileName As String) Dim opts As New Avi.AVICOMPRESSOPTIONS_CLASS() opts.fccType = CType(Avi.streamtypeVIDEO, UInteger) opts.lpParms = IntPtr.Zero opts.lpFormat = IntPtr.Zero Dim streamPointer As IntPtr = StreamPointer Avi.AVISaveOptions(IntPtr.Zero, Avi.ICMF_CHOOSE_KEYFRAME Or _ Avi.ICMF_CHOOSE_DATARATE, 1, streamPointer, opts) Avi.AVISaveOptionsFree(1, opts) Avi.AVISaveV(fileName, 0, 0, 1, aviStream, opts) End Sub End Class
VB.NET TestiProjekti
'en sen enempää selittele... Imports System Imports AviAPI Public Partial Class MainForm Public Sub New() Me.InitializeComponent() End Sub Sub Button1Click(sender As Object, e As EventArgs) Dim bitmap As Bitmap = _ CType(Image.FromFile(textBox2.Lines(0)), Bitmap) Dim aviMgr As New AviManager( _ textBox1.Text + ".avi", False) Dim aviStrm As VideoStream = _ aviMgr.AddVideoStream(True, 2, bitmap) Dim count As Integer = 0 Dim n As Integer = 1 While n < textBox2.Lines.Length If textBox2.Lines(n).Trim().Length > 0 Then bitmap = CType(Bitmap.FromFile( _ textBox2.Lines(n)), Bitmap) aviStrm.AddFrame(bitmap) bitmap.Dispose() Math.Max(System.Threading. _ Interlocked.Increment(count),count - 1) End If Math.Max(System.Threading. _ Interlocked.Increment(n),n - 1) End While aviMgr.Close() End Sub End Class
Aihe on jo aika vanha, joten et voi enää vastata siihen.