您现在的位置是:首页 >其他 >C# 调用DXGI采集屏幕网站首页其他
C# 调用DXGI采集屏幕
简介C# 调用DXGI采集屏幕
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
前言
Microsoft DirectX 图形基础结构 (DXGI) 处理枚举图形适配器、枚举显示模式、选择缓冲区格式、在进程之间共享资源 (,例如,应用程序与桌面窗口管理器 (DWM) ) 之间,以及向窗口或监视器显示呈现的帧。
本文章,主要是介绍C#使用封装好的 DXGI 采集桌面,比起传统的GDI方式,要强大很多。
一、DXGI
1.微软官方资源(都是C++语言)
2.github示例(都是C++语言)
二、基于github示例封装的dll文件
DesktopDuplication.dll下载
C++能力有限,封装的dll功能和性能都不及原github示例,测试截图正常,有能力的同学可以参考官网和github示例DIY。
三、C#调用DesktopDuplication.dll文件
1.使用流程:
将DesktopDuplication.dll下载到输出文件同级目录下,再把GXDI录屏相关代码复制到你的项目中,直接调用screenShotGXDI()方法即可。
2.封装屏幕采集大致流程:
C#通过线程初始化DesktopDuplication.dll进行屏幕采集再通过委托将DXGI采集的屏幕数据传给C#(多屏幕时通过屏幕号辨别数据是哪块屏幕)
3.C#调用示例:
#region GXDI录屏相关代码
public delegate void CallbackDelegate(IntPtr Image, int width, int height, int RowPitch, int ScreenNumber);//声明委托
//接口定义
[DllImport("DesktopDuplication.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl)]
public static extern void SetRegisterFunctionCallback(CallbackDelegate callback);
[DllImport("DesktopDuplication.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl)]
public static extern int Initialize();
[DllImport("DesktopDuplication.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl)]
private static extern int SetSwitch(int type);
public CallbackDelegate callbackDelegate = new CallbackDelegate(CallBackFunction);
[HandleProcessCorruptedStateExceptions]
public static void CallBackFunction(IntPtr Image, int width, int height, int RowPitch, int ScreenNumber)
{
try
{
Bitmap bitmap = new Bitmap(width, height, RowPitch, PixelFormat.Format32bppRgb, Image);//通过指针得到指定图片
Bitmap thumbnailimage = ThumbnailImage(bitmap, 100, 100);//计算缩量图
//ScreenNumber 屏幕号
}
catch (Exception ex)
{
Console.Write(ex.Message);
}
Thread.Sleep(30);
}
private void screenShotGXDI()
{
try
{
SetRegisterFunctionCallback(callbackDelegate);
Task task = new Task(() =>
{
Initialize();
});
task.Start();
}
catch (Exception ex)
{
DataView.PublicHandle.log(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName + "." + System.Reflection.MethodBase.GetCurrentMethod().Name, "DXGI Load Error:" + ex.Message);
}
}
/// <summary>
/// 生成缩略图
/// </summary>
/// <param name="img">原图</param>
/// <param name="maxHeight">最大高度</param>
/// <param name="maxWidth">最大宽度</param>
public static Bitmap ThumbnailImage(Bitmap img, int maxHeight, int maxWidth)
{
ImageFormat thisFormat = img.RawFormat;
//缩略图尺寸
double w = 0.0; //图片的宽
double h = 0.0; //图片的高
double sw = Convert.ToDouble(img.Width);
double sh = Convert.ToDouble(img.Height);
double mw = Convert.ToDouble(maxWidth);
double mh = Convert.ToDouble(maxHeight);
if (sw < mw && sh < mh)
{
w = sw;
h = sh;
}
else if ((sw / sh) > (mw / mh))
{
w = maxWidth;
h = (w * sh) / sw;
}
else
{
h = maxHeight;
w = (h * sw) / sh;
}
System.Drawing.Size newSize = new System.Drawing.Size(Convert.ToInt32(w), Convert.ToInt32(h));
Bitmap outBmp = new Bitmap(newSize.Width, newSize.Height);
Graphics g = Graphics.FromImage(outBmp);
//设置画布的描绘质量
g.CompositingQuality = CompositingQuality.HighQuality;
g.SmoothingMode = SmoothingMode.HighQuality;
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.DrawImage(img, new Rectangle(0, 0, newSize.Width, newSize.Height), 0, 0, img.Width, img.Height, GraphicsUnit.Pixel);
g.Dispose();
return outBmp;
}
#endregion
总结
从 Windows 8 开始,微软引入了一套新技术叫 Desktop Duplication API,应用程序可以通过这套 API 请求桌面的图形数据。
优点:由于 Desktop Duplication API 是通过 DirectX Graphics Infrastructure(以下简称 DXGI)来提供桌面图像的,竞争的是 GPU 流水线资源,所以 CPU 占用率很低,采集性能非常高。
缺点:不支持Windows8前的系统。
参考资料:
【技术分享】Windows桌面端录屏采集实现教程
风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。