首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从ImageSource创建视频

从ImageSource创建视频
EN

Stack Overflow用户
提问于 2011-06-01 05:52:43
回答 5查看 3.6K关注 0票数 11

有没有什么简单的方法可以将ImageSources添加到堆栈中并从它创建视频?

EN

回答 5

Stack Overflow用户

发布于 2011-06-10 19:35:51

我已经上过这样的课了。我只需要提交我的"ImageInfo“,这是一个system.DrawingBitmap。这可以通过使用以下代码轻松创建:

代码语言:javascript
复制
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)

代码语言:javascript
复制
    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.htmlMSDNhttp://www.codeproject.com/KB/audio-video/avigenerator.aspx

我已经发布了源代码,以展示这样的序列是什么样子的(上面的代码需要更多的参考,而这些参考不是公开的)。你可以看到,你只需要初始化,添加帧,存储FPS值,并将其保存到硬盘上。

另外,如果需要的话,你可以搜索DirectShow来看看它们是如何工作的。

票数 8
EN

Stack Overflow用户

发布于 2011-06-01 06:02:07

您可以使用

http://joshsmithonwpf.wordpress.com/2008/04/23/good-old-fashion-image-animations-in-wpf/

作为一个例子。之后,您可以使用屏幕捕获程序,如snagit或microsoft expression encoder pro,将其捕获为视频

票数 1
EN

Stack Overflow用户

发布于 2011-06-09 13:08:15

Raj在这里指出的Josh Smith的博客(http://joshsmithonwpf.wordpress.com/2008/04/23/good-old-fashion-image-animations-in-wpf/)就是在WPF应用程序中显示文件夹中的图片的一个很好的例子。

一旦这是工作,你可以看看萨维恩·雷迪的博客,将应用程序转换为视频http://blogs.msdn.com/b/saveenr/archive/2008/09/22/wpf-xaml-saving-an-animation-as-an-avi-video-file.aspx

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6194002

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档