RAM获取帧的使用
本文关键字:获取 RAM | 更新日期: 2023-09-27 18:16:40
我创建了一个c#应用程序,它在输入中接收RGB流,然后压缩流并将其保存在磁盘上。对于我的测试,我正在运行一个应用程序,作为服务器(在同一台pc上),它输出视频。
我的客户端应用程序的核心是:void client_ColorFrameReady(object sender, ColorFrameReadyEventArgs e)
{
if (writer != null)
{
count++;
if (count % 2 == 0)
writer.WriteVideoFrame(ResizeBitmap(BitmapImage2Bitmap(e.ColorFrame.BitmapImage), 320, 240));
}
else
{
writer.Close();
}
}
}
表示writer
的类型为aforge.net
库中的VideoFileWriter
。
我的应用程序运行良好,但是我有一个与RAM使用量有关的问题。
当我的应用程序从服务器应用程序(流输出视频的应用程序)获取帧时,所使用的RAM随时间线性增加。
执行writer.Close()
时释放内存。 BitmapImage2Bitmap
和ResieBitmap方法如下:
private Bitmap BitmapImage2Bitmap(BitmapImage bitmapImage)
{
// BitmapImage bitmapImage = new BitmapImage(new Uri("../Images/test.png", UriKind.Relative));
using (MemoryStream outStream = new MemoryStream())
{
BitmapEncoder enc = new BmpBitmapEncoder();
enc.Frames.Add(BitmapFrame.Create(bitmapImage));
enc.Save(outStream);
System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap(outStream);
// return bitmap; <-- leads to problems, stream is closed/closing ...
return new Bitmap(bitmap);
}
}
private static Bitmap ResizeBitmap(Bitmap sourceBMP, int width, int height)
{
Bitmap result = new Bitmap(width, height);
using (Graphics g = Graphics.FromImage(result))
g.DrawImage(sourceBMP, 0, 0, width, height);
return result;
}
我可以在我的应用程序中限制RAM的使用吗?
我总是使用
你不是。不幸的是,你也会在不该用的时候用它。每一帧都有三个位图对象被"泄露"。
在MemoryStream上使用使用会遇到麻烦。并且通过复制位图修补了这个问题,但是位图对象没有被处理。解决这个问题的正确方式,做而不是处置MemoryStream。不释放MemoryStream是可以的,当你不使用MemoryStream(Stream)构造函数时,它只使用内存并且没有可释放的成员。现在您也不再需要使用Bitmap(image)构造函数创建的副本了。这是一个.
BitmapImage2Bitmap()返回的位图没有被处理。这是两个。
ResizeBitmap()返回的位图没有被处理。三。
应该是这样的:
using (var frame = BitmapImage2Bitmap(e.ColorFrame.BitmapImage))
using (var thumb = ResizeBitmap(frame, 320, 240)) {
writer.WriteVideoFrame(thumb);
}
:
private Bitmap BitmapImage2Bitmap(BitmapImage bitmapImage)
{
var outStream = new MemoryStream();
var enc = new BmpBitmapEncoder();
enc.Frames.Add(BitmapFrame.Create(bitmapImage));
enc.Save(outStream);
return new System.Drawing.Bitmap(outStream);
}
你可能仍然有一个问题,正如我在评论中提到的,这段代码肯定比原来的代码快,避免了位图复制,但仍然不会烧橡胶。