有没有简单的方法可以将ImageSources添加到堆栈并从中创建视频?
答案 0 :(得分:8)
我已经做过这样的课程。我只需要提交我的“ImageInfo”,这是一个system.DrawingBitmap。使用以下代码可以轻松创建:
Public Function WpfBitmapSourceToBitmap(ByVal source As BitmapSource) As System.Drawing.Bitmap
If source Is Nothing Then Return Nothing
Dim bmp As New System.Drawing.Bitmap(source.PixelWidth, source.PixelHeight, System.Drawing.Imaging.PixelFormat.Format32bppPArgb)
Dim data As System.Drawing.Imaging.BitmapData = bmp.LockBits(New System.Drawing.Rectangle(System.Drawing.Point.Empty, bmp.Size), System.Drawing.Imaging.ImageLockMode.[WriteOnly], System.Drawing.Imaging.PixelFormat.Format32bppPArgb)
source.CopyPixels(Int32Rect.Empty, data.Scan0, data.Height * data.Stride, data.Stride)
bmp.UnlockBits(data)
Return bmp
End Function
然后我做了一个AviClass来添加帧并将其存储为带有预选编解码器的AVI文件(例如XVid MPEG4)
Public Class clsAviWriter
Inherits MAINInterface.TB.Imaging.Pia7.clsDspTemplate
Private cAvi As AviReaderWriter.AviFile.AviManager
Private AviStream As AviReaderWriter.AviFile.VideoStream
Private AudioStream As AviReaderWriter.AviFile.AudioStream
Private cFps As clsTbQueue
Private OldFpsDate As Date = Now
''' <summary>
''' The image object to paint graphical objects on it
''' </summary>
''' <value>descriptor of the image</value>
Public Overrides Property ImageInfo() As MAINInterface.TB.Imaging.Pia7.clsImageInfo
Get
Return Me._ImageInfo
End Get
Set(ByVal value As MAINInterface.TB.Imaging.Pia7.clsImageInfo)
Me._ImageInfo = value
Call WriteFrame()
Call Me.OnPropertyChanged(Me.Guid)
End Set
End Property
Private Sub WriteFrame()
Dim D As Date = Now
Dim Fps As Single
Me.cFps.Values.Add(D.Subtract(Me.OldFpsDate).Ticks)
Me.OldFpsDate = D
Me.cFps.Trim()
Fps = 1000 / New TimeSpan(Me.cFps.Average).TotalMilliseconds
Me.cFps.BufferSize = TB.Math.myTrim(Fps * 1, 1, 1000)
If Me.AviStream IsNot Nothing Then
Me.AviStream.AddFrame(Me._ImageInfo.Image.Clone)
End If
End Sub
Public Sub New()
Me.ClassDescription = "Write images into an avi file"
Me.cFps = New clsTbQueue(10)
End Sub
Private Sub InitializeAvi()
Dim W As String
Dim Fps As Single
Dim di As New IO.DirectoryInfo(TB.SystemMain.AppPath & "Avi\")
TB.FileSystem.CreateDirectories(di)
W = IO.Path.Combine(di.FullName, "Record_" & Now.Ticks.ToString("0") & ".avi")
Me.cAvi = New AviReaderWriter.AviFile.AviManager(W, False)
Dim Opts As New AviReaderWriter.AviFile.Avi.AVICOMPRESSOPTIONS
Opts.fccType = 0
Opts.fccHandler = 1684633208
Opts.dwKeyFrameEvery = 0
Opts.dwQuality = 0 '0 ... 10000
Opts.dwFlags = 8 'AVICOMRPESSF_KEYFRAMES = 4
Opts.dwBytesPerSecond = 0
Opts.lpFormat = 0
Opts.lpParms = New IntPtr(0)
Opts.cbParms = 3532
Opts.dwInterleaveEvery = 0
Fps = 1000 / New TimeSpan(Me.cFps.Average).TotalMilliseconds
'Dim bm1 As Bitmap
'bm1 = TB.Imaging.CreateReScaledImage(Me.pic.Image, New Size(Me.pic.Image.Width, Me.pic.Image.Height), False)
Me.AviStream = cAvi.AddVideoStream(Opts, Math.Floor(TB.Math.myTrim(Fps, 1, 50)), Me._ImageInfo.Image.Clone)
End Sub
Public Overrides Property Run() As Boolean
Get
Return Me._Run
End Get
Set(ByVal value As Boolean)
If Me._Run <> value Then
Me._Run = value
If Me._Run = True Then
Call InitializeAvi()
Else
If Me.cAvi IsNot Nothing Then
Me.cAvi.Close()
Me.cAvi = Nothing
Me.AviStream = Nothing
End If
End If
Call Me.OnPropertyChanged(Me.Guid)
End If
End Set
End Property
End Class
有关更多代码,请点击此处:http://www.wischik.com/lu/programmer/avi_utils.html和MSDN或http://www.codeproject.com/KB/audio-video/avigenerator.aspx
我发布了源代码以显示这样的序列是什么样的(上面的代码需要一些不公开的引用)。您可以看到,您只需初始化,添加帧,存储FPS值并将其安全保存到硬盘。
如果需要,您可以搜索DirectShow以查看其工作原理。
答案 1 :(得分:1)
您可以使用
http://joshsmithonwpf.wordpress.com/2008/04/23/good-old-fashion-image-animations-in-wpf/
作为一个例子。之后,您可以使用像snagit或microsoft expression encoder pro这样的屏幕捕获程序将其捕获为视频
答案 2 :(得分:1)
Josh Smith的博客在这里指出Raj(http://joshsmithonwpf.wordpress.com/2008/04/23/good-old-fashion-image-animations-in-wpf/)是一个很好的例子,可以在WPF应用程序中显示文件夹中的图像。
一旦这项工作正常,您可以查看Saveen Reddy的博客,将应用转换为视频 http://blogs.msdn.com/b/saveenr/archive/2008/09/22/wpf-xaml-saving-an-animation-as-an-avi-video-file.aspx
答案 3 :(得分:1)
使用此库avifilewrapper搜索有关如何从位图创建avi的示例代码。这个article解释了如何将视觉效果渲染到位图。我认为它不会比这更容易。
答案 4 :(得分:1)
由于WPF不包含视频编码库,因此您需要依靠外部编码库进行编码。 This blog post介绍了如何使用Windows Media Encoder执行此操作。或者,您可以将mencoder与您的应用程序捆绑在一起,并将其作为您从应用程序控制和监控的外部流程启动。