11

Is there any easy way of adding ImageSources to a stack and create a video from it?

4

5 に答える 5

8

私はすでにそのようなクラスをしました。system.DrawingBitmap である「ImageInfo」を送信するだけです。これは、次のコードを使用して簡単に作成できます。

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 を実行してフレームを追加し、事前に選択されたコーデック (XVid MPEG4 など) を使用して AVI ファイルとして保存しました。

    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 を検索してすべての動作を確認することもできます。 DirectShow ピン

于 2011-06-10T11:35:50.740 に答える
1

Raj が指摘している Josh Smith のブログ ( 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

于 2011-06-09T05:08:15.077 に答える
1

WPF にはビデオ エンコーディング ライブラリが含まれていないため、エンコーディングを行うには外部のライブラリに頼る必要があります。このブログ投稿では、Windows Media エンコーダを使用してこれを行う方法について説明します。または、mencoder のようなものをアプリにバンドルし、アプリから制御および監視する外部プロセスとして開始することもできます。

于 2011-06-10T10:22:26.717 に答える
1

使用できます

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

例として。その後、snagit や Microsoft Expression Encoder Pro などのスクリーン キャプチャ プログラムを使用して、ビデオとしてキャプチャできます。

于 2011-05-31T22:02:07.233 に答える
1

このライブラリavifilewrapper検索を使用して、ビットマップから avi を作成する方法に関するサンプル コードを検索します。この記事では、ビジュアルをビットマップにレンダリングする方法について説明します。これ以上簡単にはいかないと思います。

于 2011-06-09T16:29:46.300 に答える