在C#中将Vlc.DotNet.Form快照保存至Bitmap变量
在C#中将VLC控件的视频快照存入内存而非硬盘文件
当前项目中使用vlcControl1.TakeSnapshot(@"D:\a.jpg", 600, 400);会将UDP视频流的快照保存到硬盘,以下两种方案可实现将快照直接存入内存变量:
方案一:利用LibVLCSharp的SnapshotTaken事件(推荐,适用于新版本控件)
如果使用的是基于LibVLCSharp的VlcControl,可通过订阅SnapshotTaken事件获取内存中的快照数据,无需写入文件:
- 初始化时订阅事件:
vlcControl1.SnapshotTaken += VlcControl1_SnapshotTaken;
- 触发快照(无需指定文件路径):
// 0表示视频轨道索引,指定宽高600x400 vlcControl1.MediaPlayer.TakeSnapshot(0, 600, 400);
- 处理事件获取内存快照:
private byte[] _snapshotBytes; // 类级别的内存变量,用于存储快照字节 private Image _snapshotImage; // 如需Image对象可使用此变量 private void VlcControl1_SnapshotTaken(object sender, SnapshotTakenEventArgs e) { // 获取快照的字节数组 _snapshotBytes = e.Data; // 可选:将字节数组转换为Image对象 using (var ms = new MemoryStream(_snapshotBytes)) { _snapshotImage = Image.FromStream(ms); // 此处可直接使用_snapshotImage进行后续处理 } }
方案二:设置视频回调实时获取帧数据(适用于旧版本Vlc.DotNet控件)
如果控件没有提供SnapshotTaken事件,可通过设置视频回调函数,直接从VLC的帧缓冲区获取数据存入内存:
- 初始化时配置视频回调:
// 设置视频格式为RV32(32位RGB),宽高600x400,每行字节数=宽度*4 vlcControl1.MediaPlayer.SetVideoFormat("RV32", 600, 400, 600 * 4); vlcControl1.MediaPlayer.SetVideoCallbacks(VideoLockCallback, VideoUnlockCallback, null);
- 实现回调函数处理帧数据:
private byte[] _currentSnapshot; // 存储最新快照的内存变量 private IntPtr VideoLockCallback(IntPtr opaque, out IntPtr planes) { // 为单帧数据分配内存(600*400*4字节,对应32位RGB) var buffer = Marshal.AllocHGlobal(600 * 400 * 4); planes = buffer; return buffer; } private void VideoUnlockCallback(IntPtr opaque, IntPtr picture, IntPtr[] planes) { // 将帧数据从非托管内存复制到字节数组 byte[] frameData = new byte[600 * 400 * 4]; Marshal.Copy(planes[0], frameData, 0, frameData.Length); // 转换为JPEG格式的字节数组存入内存 using (var ms = new MemoryStream()) using (var bmp = new Bitmap(600, 400, PixelFormat.Format32bppRgb)) { var bitmapData = bmp.LockBits( new Rectangle(0, 0, 600, 400), ImageLockMode.WriteOnly, PixelFormat.Format32bppRgb ); Marshal.Copy(frameData, 0, bitmapData.Scan0, frameData.Length); bmp.UnlockBits(bitmapData); bmp.Save(ms, ImageFormat.Jpeg); _currentSnapshot = ms.ToArray(); } // 释放分配的非托管内存 Marshal.FreeHGlobal(planes[0]); }
需要快照时,直接使用_currentSnapshot变量即可,它会实时存储最新的视频帧数据。
内容的提问来源于stack exchange,提问作者user2687117
相关产品推荐
相关产品推荐

