Có cách nào dễ dàng để thêm ImageSources vào ngăn xếp và tạo video từ đó không?Tạo Video từ ImageSource
Trả lời
Bạn có thể sử dụng
http://joshsmithonwpf.wordpress.com/2008/04/23/good-old-fashion-image-animations-in-wpf/
làm ví dụ. Sau đó, bạn có thể sử dụng chương trình chụp ảnh màn hình như snagit hoặc bộ mã hóa biểu thức microsoft để chụp ảnh dưới dạng video
Cảm ơn bạn đã trả lời nhanh. Vâng, nhưng tôi sẽ rahter như simething mà đầu ra một AVI không nén hoặc một cái gì đó: D – Anders
Blog của Josh Smith chỉ bởi Raj ở đây (http://joshsmithonwpf.wordpress.com/2008/04/23/good-old-fashion-image-animations-in-wpf/) là ví dụ tốt về hiển thị hình ảnh từ một thư mục trong ứng dụng WPF.
Một khi điều này đang làm việc bạn có thể nhìn vào blog của Saveen Reddy để chuyển đổi ứng dụng sang video http://blogs.msdn.com/b/saveenr/archive/2008/09/22/wpf-xaml-saving-an-animation-as-an-avi-video-file.aspx
Vâng, đó không phải là một vấn đề, tôi hiểu cách tiếp cận của mình. Nhưng phải có một API hoặc một cái gì đó để tạo ra một không nén AVI vv từ hình ảnh? Cảm ơn. – Anders
Sử dụng này thư viện avifilewrapper tìm kiếm các mẫu mã trên như thế nào để tạo ra một avi từ bitmap. Điều này article giải thích cách bạn có thể hiển thị hình ảnh của mình thành bitmap. Tôi không nghĩ nó sẽ dễ dàng hơn thế.
Vì WPF không bao gồm thư viện mã hóa video, bạn sẽ cần phải dựa vào một thư viện bên ngoài để thực hiện mã hóa. This blog post mô tả cách bạn có thể sử dụng Windows Media Encoder để làm như vậy. Ngoài ra, bạn có thể nhóm thứ gì đó như mencoder với ứng dụng của mình và khởi động nó như một quá trình bên ngoài mà bạn kiểm soát và giám sát từ ứng dụng của mình.
Tôi đã thực hiện một lớp học như vậy. Tôi chỉ phải gửi "ImageInfo" của tôi, đó là system.DrawingBitmap. Điều này có thể được tạo ra dễ dàng bằng cách sử dụng đoạn mã sau:
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
Sau đó, tôi đã làm một AviClass để thêm khung hình để nó và lưu nó như một tập tin AVI với chọn trước Codec (ví dụ 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
Đối với mã hơn xem ở đây: http://www.wischik.com/lu/programmer/avi_utils.html và MSDN hoặc http://www.codeproject.com/KB/audio-video/avigenerator.aspx
tôi đã đăng sourcecode cho thấy làm thế nào một chuỗi như vậy có thể trông giống như (mã trên cần một số tài liệu tham khảo hơn là không được công khai có sẵn). Bạn có thể thấy rằng bạn chỉ cần khởi tạo, thêm khung, lưu trữ giá trị FPS và an toàn nó vào đĩa cứng.
Ngoài ra nếu muốn, bạn có thể tìm kiếm DirectShow để xem cách hoạt động của tất cả.
Nếu tôi có thể upvote điều này thêm một vài lần tôi muốn. Đây là điều tôi rất muốn có thể làm. – Tim