c# - 将截屏时间缩短至 40 毫秒
问题描述
我正在截屏,将其缩小到分辨率的 50%,以占用更少的空间,然后我将字节放入 中buffer
,但不幸的是,这个过程需要太多时间。
目前,1920x1080 源分辨率需要 60 到 100 毫秒,这导致 30fps 的输出视频速度加快,因为我生成屏幕截图的速度不够快。我需要达到大约 40 毫秒才能制作流畅的视频。
问题:如何应用更快的插值算法或限制所需的操作以加快速度?
public void Screenshot(byte[] buffer)
{
using (var bmp = new Bitmap(Params.SourceWidth, Params.SourceHeight))
{
using (var g = Graphics.FromImage(bmp))
{
g.CopyFromScreen(Point.Empty, Point.Empty, new Size(Params.SourceWidth, Params.SourceHeight), CopyPixelOperation.SourceCopy);
g.Flush();
using (Bitmap resized = new Bitmap(bmp, new Size(Params.TargetWidth, Params.TargetHeight)))
{
var bits = resized.LockBits(new Rectangle(0, 0, Params.TargetWidth, Params.TargetHeight), ImageLockMode.ReadOnly, PixelFormat.Format32bppRgb);
Marshal.Copy(bits.Scan0, buffer, 0, buffer.Length);
resized.UnlockBits(bits);
}
}
}
}
解决方案
这种方法很慢,因为您使用的是 GDI,它不再是 Windows 中的主要图形 API(自 Windows Vista 以来就没有了)。它速度慢的原因之一是它会将图像数据从 GPU 的内存 (VRAM) 复制到计算机的主内存 (RAM) 中,以便通过 GDI 对其进行操作。
如果您想在计算机的帧缓冲区上进行快速操作,请使用 DWM API 并仅在 GPU 的缓冲区之间复制内存。您也可以通过将它们作为着色器或 CUDA 程序来快速进行图像调整大小和其他操作。
推荐阅读
- android - 在 oreo 8.1.0 中我无法获取 fcm 设备 ID
- java - POST 请求与 POSTMAN/Advance rest 客户端一起正常工作,同时使用 HttpUrlConnection 给出 400 错误
- firebase - 无法访问 Firestore 云函数中的 Firestore 文档
- php - 在 React Native 中将数据插入 MySQL 数据库时出现 JSON 解析错误
- javascript - 使用自调用函数时,为什么不能传递引用?
- java - Intellij 在文件末尾自动生成 java 方法
- python - ImportError:DLL 加载失败:我使用 python 2.7 下载 scipy for windows 64 后找不到指定的模块
- jmeter - 如何忽略损坏的资源以在 JMeter 中获取失败的 HTTP 请求
- amazon-web-services - 创建状态存储桶时,远程后端 S3 的 Terraform 初始化失败
- reactjs - 如何在 React Application for Adobe 分析(adobe 启动)中实现数据层?