我正在制作录音应用程序,我每秒可以获得10到15个截图。 问题是如何快速保存所有图像,以便屏幕截图队列不会在RAM中累积并消耗用户的内存。
目前我可以通过使用两个线程按顺序保存图像然后收集垃圾来实现这一点。
while (true)
{
bmp = null;
Dispatcher.Invoke(new Action(delegate()
{
if (images.Count > 0)
{
bmp = images[0];
images.RemoveAt(0);
}
}));
if (bmp != null)
{
bmp.Save("frames\\" + framesImagesIndex++ + ".png", ImageFormat.Png);
bmp.Dispose();
bmp = null;
GC.Collect();
}
Thread.Sleep(10);
}
这个问题是它非常占用CPU,所以我认为它不会在功能较弱的系统上运行。这种方法在我的3.31 GHz进程上需要30个CPU。
当我将CPU设置为将所有图像写入一个文件并通过锁定位图的位来写入字节时,我可以将CPU减轻到17左右。
byte[] rgbValues;
IntPtr ptr;
System.Drawing.Rectangle rect;
System.Drawing.Imaging.BitmapData bmpData;
System.Drawing.Imaging.PixelFormat pxf;
pxf = System.Drawing.Imaging.PixelFormat.Format24bppRgb;
//using(FileStream fs = new FileStream("frames.data", FileMode.OpenOrCreate, FileAccess.Write))
while (true)
{
bmp = null;
Dispatcher.Invoke(new Action(delegate()
{
if (images.Count > 0)
{
bmp = images[0];
images.RemoveAt(0);
}
}));
rect = new System.Drawing.Rectangle(0, 0, bmp.Width, bmp.Height);
bmpData = bmp.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadOnly, pxf);
ptr = bmpData.Scan0;
rgbValues = new byte[bmpData.Stride * bmp.Height];
Marshal.Copy(ptr, rgbValues, 0, rgbValues.Length);
fs.Write(rgbValues, 0, rgbValues.Length);
bmp.UnlockBits(bmpData);
bmp.Dispose();
bmp = null;
GC.Collect();
}
这种方法有助于CPU发布,但因为它不够快。图像队列累积并使ram超载,所以我不知道我还能做些什么来解决这两个问题。
还有其他方法吗?
答案 0 :(得分:0)
首先,使用带有while
的{{1}}循环非常占用CPU,Thread.Sleep(x);
也是如此,并且经常调用新实例。
你应该考虑使用线程。
GC.Collect()
尝试使用上述内容,或者至少集成一些部分。