You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在C#中将Vlc.DotNet.Form快照保存至Bitmap变量

在C#中将VLC控件的视频快照存入内存而非硬盘文件

当前项目中使用vlcControl1.TakeSnapshot(@"D:\a.jpg", 600, 400);会将UDP视频流的快照保存到硬盘,以下两种方案可实现将快照直接存入内存变量:

方案一:利用LibVLCSharp的SnapshotTaken事件(推荐,适用于新版本控件)

如果使用的是基于LibVLCSharp的VlcControl,可通过订阅SnapshotTaken事件获取内存中的快照数据,无需写入文件:

  1. 初始化时订阅事件:
vlcControl1.SnapshotTaken += VlcControl1_SnapshotTaken;
  1. 触发快照(无需指定文件路径):
// 0表示视频轨道索引,指定宽高600x400
vlcControl1.MediaPlayer.TakeSnapshot(0, 600, 400);
  1. 处理事件获取内存快照:
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的帧缓冲区获取数据存入内存:

  1. 初始化时配置视频回调:
// 设置视频格式为RV32(32位RGB),宽高600x400,每行字节数=宽度*4
vlcControl1.MediaPlayer.SetVideoFormat("RV32", 600, 400, 600 * 4);
vlcControl1.MediaPlayer.SetVideoCallbacks(VideoLockCallback, VideoUnlockCallback, null);
  1. 实现回调函数处理帧数据:
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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 02:32:40