Pregunta Crear video desde ImageSource


¿Hay alguna manera fácil de agregar ImageSources a una pila y crear un video a partir de ella?


11
2018-05-31 21:52


origen


Respuestas:


Ya hice tal clase. Solo tengo que enviar mi "ImageInfo" que es un system.DrawingBitmap. Esto se puede crear fácilmente usando el siguiente código:

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

Luego hice un AviClass para agregar marcos y almacenarlo como un archivo AVI con códec preseleccionado (por ejemplo, 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

Para ver más códigos, mira aquí: http://www.wischik.com/lu/programmer/avi_utils.html y MSDN o http://www.codeproject.com/KB/audio-video/avigenerator.aspx

He publicado el código fuente para mostrar cómo se ve una secuencia así (el código anterior necesita algunas referencias más que no están disponibles para el público). Puede ver que solo necesita inicializar, agregar marcos, almacenar el valor de FPS y protegerlo en el disco duro.

Además, si lo desea, puede buscar DirectShow para ver cómo funciona todo. DirectShow Pins


8
2018-06-10 11:35



Puedes usar

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

como ejemplo. Luego puede usar un programa de captura de pantalla como snagit o microsoft expression codder pro para capturarlo como un video


1
2018-05-31 22:02



El blog de Josh Smith señalado por Raj aquí (http://joshsmithonwpf.wordpress.com/2008/04/23/good-old-fashion-image-animations-in-wpf/) es un buen ejemplo de mostrar imágenes de una carpeta en la aplicación WPF.

Una vez que esto esté funcionando, puedes mirar el blog de Saveen Reddy para convertir la aplicación a video http://blogs.msdn.com/b/saveenr/archive/2008/09/22/wpf-xaml-saving-an-animation-as-an-avi-video-file.aspx


1
2018-06-09 05:08



Usa esta biblioteca avifilewrapper busque el código de ejemplo sobre cómo crear un avi desde mapas de bits. Esta artículo explica cómo puede renderizar sus imágenes en mapas de bits. No creo que sea más fácil que eso.


1
2018-06-09 16:29



Como WPF no incluye bibliotecas de codificación de video, necesitará apoyarse en una externa para hacer la codificación. Esta publicación de blog describe cómo puede usar Windows Media Encoder para hacerlo. Alternativamente, podría agrupar algo como mencoder con su aplicación e iniciarlo como un proceso externo que usted controla y supervisa desde su aplicación.


1
2018-06-10 10:22