我创建了一个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
库的VideoFileWriter
类型为aforge.net
。
我的应用程序运行良好,但我遇到了与使用的RAM量有关的问题。
当我的应用程序获取帧时,从服务器应用程序(流出视频的应用程序)使用的RAM随时间线性增加。只有在执行writer.Close()
时才释放RAM。
方法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的使用吗?
答案 0 :(得分:4)
我总是使用
你不是。不幸的是,你也应该使用它。每个帧都有三个位图对象“泄露”。
在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);
}
你可能仍然有一个firehose问题,正如我在评论中提到的那样,这段代码肯定比原版快,避免了位图复制,但仍然不会烧橡胶。