如何在 C# 中的数组中存储相机流数据



我需要在RAM中存储五分钟的流数据(或替代方案,如果可用的话。现在我只知道RAM(。我知道如何将数据转换为 bmp 图像,并使用字节将它们存储在列表中,使用Marshal.copy

但是每帧的大小约为3Mb,这对于RAM来说太大而无法存储。

我相信,如果我简单地将字节存储在数组中,数据的大小可能会小得多,但我不知道如何。此时此刻,我不太清楚整个元帅的事情,寻找将指针值复制到托管数组的方法的日子是徒劳的。 我需要帮助。

我错过了什么? 为什么我不能将可用于存储为 BMP 的块复制为简单的字节数组? 如何将以下函数转换为返回数组的函数?

这是我用来将数据转换为BMP的代码,我需要能够进行必要的更改以将其转换为收集列表或数组中所有数据的函数。

private Bitmap GetBitmap(ISampleGrabber i_grabber, int width, int height, int stride)
{
int sz = 0;
i_grabber.GetCurrentBuffer(ref sz, IntPtr.Zero); 
if (sz == 0) return null;
var ptr = Marshal.AllocCoTaskMem(sz);
i_grabber.GetCurrentBuffer(ref sz, ptr);
var data = new byte[sz];
Marshal.Copy(ptr, data, 0, sz);
Bitmap result = null;
try
{
result = new Bitmap(width, height, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
var bmp_data = result.LockBits(new Rectangle(Point.Empty, result.Size), System.Drawing.Imaging.ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
for (int y = 0; y < height; y++)
{
var src_idx = sz - (stride * (y + 1));
//Console.WriteLine(src_idx);
var dst = new IntPtr(bmp_data.Scan0.ToInt32() + (stride * y));
Marshal.Copy(data, src_idx, dst, stride);
}
result.UnlockBits(bmp_data);
Marshal.FreeCoTaskMem(ptr);
}
catch (ArgumentException ax)
{
//System.Windows.Forms.MessageBox.Show(ax.Message);
Console.WriteLine(ax.Message);
}
return result;
}

每帧 3 兆字节、每秒 300 秒和 N 帧可能会使其对于 RAM 来说太大。随着视频捕获的进行,您必须对数据做一些事情。

给你的一些想法:

  1. 压缩 - 如果您可以实时压缩数据,您的存储需求将大大降低,包括在 RAM 中提供 300 秒的存储,甚至可能使用无损编码

1.1.硬件辅助压缩(需要GPU,在某些情况下可以是无损的(;输出对于 RAM 和磁盘写入来说很好

1.2. 使用众所周知的格式(高 CPU 负载(进行软件压缩;数据将适合 RAM

1.3. 一些使用简单众所周知的算法的轻量级压缩可能是无损的;根据内容的不同,即使是简单的后处理也很可能会减少要保留的数据量

    异步磁盘写入 - 如果在捕获时写入,
  1. 则数据量可能太大,无法实时写入临时磁盘位置,但是异步写入而不阻止捕获可以将您刷新足够的数据到磁盘,并且其余数据在视频捕获的第五分钟时适合可用 RAM。

最新更新