用于保存位图的 C# 更快方法
本文关键字:方法 保存 位图 用于 | 更新日期: 2023-09-27 18:33:27
我正在开发一个录音应用程序,每秒能够获得 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,所以我不知道我还能做些什么来解决这两个问题。
还有其他方法吗?
首先,使用带有Thread.Sleep(x);
的 while
循环非常占用 CPU,就像GC.Collect()
和频繁调用新实例一样。您应该考虑使用线程。
Action action;
public void Main()
{
action = new Action(delegate()
{
if (images.Count > 0)
{
bmp = images[0];
images.RemoveAt(0);
}
});
Thread thread = new Thread(SaveBitmap());
thread.Start();
thread.Priority = ThreadPriority.Highest
}
public void SaveBitmap()
{
Dispatcher.Invoke(action);
if (bmp != null)
{
bmp.Save("frames''" + framesImagesIndex++ + ".png", ImageFormat.Png);
bmp.Dispose();
bmp = null;
}
}
尝试使用上述方法,或者至少集成一些部分。
由于涉及压缩,另存为 PNG 格式会占用大量 CPU。将图像另存为.bmp,您将获得很大的速度提升,但代价是使用更多磁盘空间。