You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何获取显示器图像数据?Electron.js下实现含鼠标的透明背景截图

解决方案与问题解答

1. 实现带鼠标光标、支持透明背景的截图功能(少用第三方库)

你的核心需求是捕获包含鼠标光标、且保留屏幕真实内容(包括透明窗口后的画面)的截图,以下分平台给出无/少依赖的实现方案:

Windows平台

方案1:调用PowerShell+系统API(无第三方库)

通过child_process.exec()调用PowerShell命令,结合.NET类库捕获屏幕+鼠标光标:

const { exec } = require('child_process');

exec(`powershell -Command "
Add-Type -AssemblyName System.Windows.Forms,System.Drawing;
# 捕获屏幕到剪贴板
[System.Windows.Forms.SendKeys]::SendWait('{PRTSC}');
Start-Sleep -Milliseconds 100;
# 获取剪贴板中的图像
$bmp = [System.Windows.Forms.Clipboard]::GetImage();
# 获取鼠标位置
$cursorPos = [System.Windows.Forms.Cursor]::Position;
# 创建Graphics对象以绘制光标
$g = [System.Drawing.Graphics]::FromImage($bmp);
# 获取当前光标并绘制到截图上
$cursor = [System.Windows.Forms.Cursor]::Current;
$cursor.Draw($g, [System.Drawing.Rectangle]::new($cursorPos.X, $cursorPos.Y, $cursor.Size.Width, $cursor.Size.Height));
# 保存图像
$bmp.Save('screen_capture.png', [System.Drawing.Imaging.ImageFormat]::Png);
"`, (err) => {
  if (err) console.error(err);
});

该方案利用Windows自带的.NET类库,无需额外安装依赖,能完整捕获屏幕+鼠标,且透明窗口后的内容会被正常保留(因为是捕获整个屏幕)。

方案2:直接调用Windows原生API(依赖ffi-napi)

如果需要更灵活的控制(如指定捕获区域),可以用ffi-napi调用User32.dll和Gdi32.dll的API,核心逻辑:获取屏幕DC→创建兼容位图→复制屏幕内容→获取鼠标位置并绘制光标→保存图像。

macOS平台

直接调用系统自带的screencapture命令,该命令支持捕获鼠标光标,且能保留屏幕所有内容(包括透明窗口后的画面):

const { exec } = require('child_process');

exec('screencapture -C screen_capture.png', (err) => {
  if (err) console.error(err);
});

参数-C表示包含鼠标光标,无需任何第三方库,输出的PNG图像会完整保留屏幕的真实显示效果。

Linux平台

根据桌面环境选择预装的截图工具:

  • GNOME桌面:gnome-screenshot -p screen_capture.png(-p参数包含鼠标光标)
  • KDE桌面:spectacle -b -o screen_capture.png(-b捕获整个屏幕,默认包含光标)
  • 通用方案:scrot -u screen_capture.png(需提前安装scrot:sudo apt install scrot)

通过child_process.exec()调用上述命令即可实现需求。

2. 显示器图像数据的生成逻辑

最终显示在显示器上的图像是由**GPU(显卡)**主导生成的:

  1. 操作系统的窗口管理器收集所有应用的窗口绘制请求(如Electron应用的Chromium渲染进程生成的帧);
  2. GPU将这些窗口帧作为独立图层,进行合成处理(包括叠加、透明度计算、变换等);
  3. 合成后的完整屏幕帧被写入显卡的帧缓冲区;
  4. 显卡通过视频输出接口(HDMI/DP/VGA等)将帧缓冲区的数据逐行发送给显示器,最终呈现为屏幕画面。

3. 额外问题解答

透明区域为何被处理成#000000?

你用Electron.BrowserWindow.capturePage()时出现的黑色透明区域,原因有两点:

  • capturePage()仅捕获当前窗口的DOM渲染内容,不包含窗口外的屏幕内容,所以窗口透明区域(无DOM元素覆盖的部分)会填充默认的黑色(图像的alpha通道未被正确保留或直接忽略);
  • 部分图像格式(如JPG)不支持alpha通道,即使是PNG格式,如果捕获逻辑未正确处理透明通道,也会将透明区域替换为黑色。

部分程序无法被截图,显示黑色?

这类程序通常通过以下方式阻止截图:

  • Windows:调用SetWindowDisplayAffinity API,设置窗口的显示亲和力为WDA_MONITOR,禁止截图工具捕获窗口内容;
  • macOS:启用系统权限中的“屏幕录制”限制,或调用CGDisplayStreamCreateWithWindow等API标记窗口为不可捕获;
  • DRM保护:视频播放、付费内容类程序会利用数字版权管理技术,让GPU直接渲染内容,不允许屏幕捕获工具读取帧数据,此时截图会返回黑色或空白画面。

内容的提问来源于stack exchange,提问作者Doohyeon Won

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 08:10:24