capture-screen

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Capture Screen

屏幕截图

Programmatic screenshot capture on macOS: find windows, control views, capture images.
在macOS上实现程序化截图:查找窗口、控制视图、捕获图像。

Quick Start

快速开始

bash
undefined
bash
undefined

Find Excel window ID

Find Excel window ID

swift scripts/get_window_id.swift Excel
swift scripts/get_window_id.swift Excel

Capture that window (replace 12345 with actual WID)

Capture that window (replace 12345 with actual WID)

screencapture -x -l 12345 output.png
undefined
screencapture -x -l 12345 output.png
undefined

Overview

概述

Three-step workflow:
1. Find Window  →  Swift CGWindowListCopyWindowInfo  →  get numeric Window ID
2. Control View  →  AppleScript (osascript)           →  zoom, scroll, select
3. Capture       →  screencapture -l <WID>            →  PNG/JPEG output
三步工作流:
1. 查找窗口  →  Swift CGWindowListCopyWindowInfo  → 获取数字格式的窗口ID
2. 控制视图  →  AppleScript (osascript)           → 缩放、滚动、选择
3. 捕获截图  →  screencapture -l <WID>            → 输出PNG/JPEG格式

Step 1: Get Window ID (Swift)

步骤1:获取窗口ID(Swift)

Use Swift with CoreGraphics to enumerate windows. This is the only reliable method on macOS.
使用Swift结合CoreGraphics枚举窗口。这是macOS上唯一可靠的方法

Quick inline execution

快速内联执行

bash
swift -e '
import CoreGraphics
let keyword = "Excel"
let list = CGWindowListCopyWindowInfo(.optionOnScreenOnly, kCGNullWindowID) as? [[String: Any]] ?? []
for w in list {
    let owner = w[kCGWindowOwnerName as String] as? String ?? ""
    let name = w[kCGWindowName as String] as? String ?? ""
    let wid = w[kCGWindowNumber as String] as? Int ?? 0
    if owner.localizedCaseInsensitiveContains(keyword) || name.localizedCaseInsensitiveContains(keyword) {
        print("WID=\(wid) | App=\(owner) | Title=\(name)")
    }
}
'
bash
swift -e '
import CoreGraphics
let keyword = "Excel"
let list = CGWindowListCopyWindowInfo(.optionOnScreenOnly, kCGNullWindowID) as? [[String: Any]] ?? []
for w in list {
    let owner = w[kCGWindowOwnerName as String] as? String ?? ""
    let name = w[kCGWindowName as String] as? String ?? ""
    let wid = w[kCGWindowNumber as String] as? Int ?? 0
    if owner.localizedCaseInsensitiveContains(keyword) || name.localizedCaseInsensitiveContains(keyword) {
        print("WID=\(wid) | App=\(owner) | Title=\(name)")
    }
}
'

Using the bundled script

使用捆绑脚本

bash
swift scripts/get_window_id.swift Excel
swift scripts/get_window_id.swift Chrome
swift scripts/get_window_id.swift          # List all windows
Output format:
WID=12345 | App=Microsoft Excel | Title=workbook.xlsx
Parse the WID number for use with
screencapture -l
.
bash
swift scripts/get_window_id.swift Excel
swift scripts/get_window_id.swift Chrome
swift scripts/get_window_id.swift          # List all windows
输出格式:
WID=12345 | App=Microsoft Excel | Title=workbook.xlsx
解析出WID编号,用于
screencapture -l
命令。

Step 2: Control Window (AppleScript)

步骤2:控制窗口(AppleScript)

Verified commands for controlling application windows before capture.
以下是经过验证的、可在截图前控制应用窗口的命令。

Microsoft Excel (full AppleScript support)

Microsoft Excel(完整AppleScript支持)

bash
undefined
bash
undefined

Activate (bring to front)

Activate (bring to front)

osascript -e 'tell application "Microsoft Excel" to activate'
osascript -e 'tell application "Microsoft Excel" to activate'

Set zoom level (percentage)

Set zoom level (percentage)

osascript -e 'tell application "Microsoft Excel" set zoom of active window to 120 end tell'
osascript -e 'tell application "Microsoft Excel" set zoom of active window to 120 end tell'

Scroll to specific row

Scroll to specific row

osascript -e 'tell application "Microsoft Excel" set scroll row of active window to 45 end tell'
osascript -e 'tell application "Microsoft Excel" set scroll row of active window to 45 end tell'

Scroll to specific column

Scroll to specific column

osascript -e 'tell application "Microsoft Excel" set scroll column of active window to 3 end tell'
osascript -e 'tell application "Microsoft Excel" set scroll column of active window to 3 end tell'

Select a cell range

Select a cell range

osascript -e 'tell application "Microsoft Excel" select range "A1" of active sheet end tell'
osascript -e 'tell application "Microsoft Excel" select range "A1" of active sheet end tell'

Select a specific sheet

Select a specific sheet

osascript -e 'tell application "Microsoft Excel" activate object sheet "DCF" of active workbook end tell'
osascript -e 'tell application "Microsoft Excel" activate object sheet "DCF" of active workbook end tell'

Open a file

Open a file

osascript -e 'tell application "Microsoft Excel" open POSIX file "/path/to/file.xlsx" end tell'
undefined
osascript -e 'tell application "Microsoft Excel" open POSIX file "/path/to/file.xlsx" end tell'
undefined

Any application (basic control)

任意应用(基础控制)

bash
undefined
bash
undefined

Activate any app

Activate any app

osascript -e 'tell application "Google Chrome" to activate'
osascript -e 'tell application "Google Chrome" to activate'

Bring specific window to front (by index)

Bring specific window to front (by index)

osascript -e 'tell application "System Events" tell process "Google Chrome" perform action "AXRaise" of window 1 end tell end tell'
undefined
osascript -e 'tell application "System Events" tell process "Google Chrome" perform action "AXRaise" of window 1 end tell end tell'
undefined

Timing and Timeout

计时与超时

Always add
sleep 1
after AppleScript commands before capturing, to allow UI rendering to complete.
IMPORTANT:
osascript
hangs indefinitely if the target application is not running or not responding. Always wrap with
timeout
:
bash
timeout 5 osascript -e 'tell application "Microsoft Excel" to activate'
在执行AppleScript命令后、捕获截图前,务必添加
sleep 1
命令,等待UI渲染完成。
重要提示:如果目标应用未运行或无响应,
osascript
会无限期挂起。务必用
timeout
命令包裹:
bash
timeout 5 osascript -e 'tell application "Microsoft Excel" to activate'

Step 3: Capture (screencapture)

步骤3:捕获截图(screencapture)

bash
undefined
bash
undefined

Capture specific window by ID

Capture specific window by ID

screencapture -l <WID> output.png
screencapture -l <WID> output.png

Silent capture (no camera shutter sound)

Silent capture (no camera shutter sound)

screencapture -x -l <WID> output.png
screencapture -x -l <WID> output.png

Capture as JPEG

Capture as JPEG

screencapture -l <WID> -t jpg output.jpg
screencapture -l <WID> -t jpg output.jpg

Capture with delay (seconds)

Capture with delay (seconds)

screencapture -l <WID> -T 2 output.png
screencapture -l <WID> -T 2 output.png

Capture a screen region (interactive)

Capture a screen region (interactive)

screencapture -R x,y,width,height output.png
undefined
screencapture -R x,y,width,height output.png
undefined

Retina displays

Retina显示屏

On Retina Macs,
screencapture
outputs 2x resolution by default (e.g., a 2032x1238 window produces a 4064x2476 PNG). This is normal. To get 1x resolution, resize after capture:
bash
sips --resampleWidth 2032 output.png --out output_1x.png
在Retina Mac上,
screencapture
默认输出2倍分辨率的截图(例如,一个2032x1238的窗口会生成4064x2476的PNG图片)。这是正常现象。如需获取1倍分辨率的截图,请在捕获后调整大小:
bash
sips --resampleWidth 2032 output.png --out output_1x.png

Verify capture

验证截图

bash
undefined
bash
undefined

Check file was created and has content

Check file was created and has content

ls -la output.png file output.png # Should show "PNG image data, ..."
undefined
ls -la output.png file output.png # Should show "PNG image data, ..."
undefined

Multi-Shot Workflow

多镜头工作流

Complete example: capture multiple sections of an Excel workbook.
bash
undefined
完整示例:捕获Excel工作簿的多个区域。
bash
undefined

1. Open file and activate Excel

1. Open file and activate Excel

osascript -e 'tell application "Microsoft Excel" open POSIX file "/path/to/model.xlsx" activate end tell' sleep 2
osascript -e 'tell application "Microsoft Excel" open POSIX file "/path/to/model.xlsx" activate end tell' sleep 2

2. Set up view

2. Set up view

osascript -e 'tell application "Microsoft Excel" set zoom of active window to 130 activate object sheet "Summary" of active workbook end tell' sleep 1
osascript -e 'tell application "Microsoft Excel" set zoom of active window to 130 activate object sheet "Summary" of active workbook end tell' sleep 1

3. Get window ID

3. Get window ID

IMPORTANT: Always re-fetch before capturing. CGWindowID is invalidated

IMPORTANT: Always re-fetch before capturing. CGWindowID is invalidated

when an app restarts or a window is closed and reopened.

when an app restarts or a window is closed and reopened.

WID=$(swift -e ' import CoreGraphics let list = CGWindowListCopyWindowInfo(.optionOnScreenOnly, kCGNullWindowID) as? [[String: Any]] ?? [] for w in list { let owner = w[kCGWindowOwnerName as String] as? String ?? "" let wid = w[kCGWindowNumber as String] as? Int ?? 0 if owner == "Microsoft Excel" { print(wid); break } } ') echo "Window ID: $WID"
WID=$(swift -e ' import CoreGraphics let list = CGWindowListCopyWindowInfo(.optionOnScreenOnly, kCGNullWindowID) as? [[String: Any]] ?? [] for w in list { let owner = w[kCGWindowOwnerName as String] as? String ?? "" let wid = w[kCGWindowNumber as String] as? Int ?? 0 if owner == "Microsoft Excel" { print(wid); break } } ') echo "Window ID: $WID"

4. Capture Section A (top of sheet)

4. Capture Section A (top of sheet)

osascript -e 'tell application "Microsoft Excel" set scroll row of active window to 1 end tell' sleep 1 screencapture -x -l $WID section_a.png
osascript -e 'tell application "Microsoft Excel" set scroll row of active window to 1 end tell' sleep 1 screencapture -x -l $WID section_a.png

5. Capture Section B (further down)

5. Capture Section B (further down)

osascript -e 'tell application "Microsoft Excel" set scroll row of active window to 45 end tell' sleep 1 screencapture -x -l $WID section_b.png
osascript -e 'tell application "Microsoft Excel" set scroll row of active window to 45 end tell' sleep 1 screencapture -x -l $WID section_b.png

6. Switch sheet and capture

6. Switch sheet and capture

osascript -e 'tell application "Microsoft Excel" activate object sheet "DCF" of active workbook set scroll row of active window to 1 end tell' sleep 1 screencapture -x -l $WID dcf_overview.png
undefined
osascript -e 'tell application "Microsoft Excel" activate object sheet "DCF" of active workbook set scroll row of active window to 1 end tell' sleep 1 screencapture -x -l $WID dcf_overview.png
undefined

Failed Approaches (DO NOT USE)

已废弃的方法(请勿使用)

These methods were tested and confirmed to fail on macOS:
MethodErrorWhy It Fails
System Events
id of window
Error -1728System Events cannot access window IDs in the format screencapture needs
Python
import Quartz
(PyObjC)
ModuleNotFoundError
PyObjC not installed in system Python; don't attempt to install it — use Swift instead
osascript
window id
Wrong formatReturns AppleScript window index, not CGWindowID needed by
screencapture -l
以下方法已测试确认在macOS上无法正常工作:
方法错误失败原因
System Events
id of window
Error -1728System Events无法以screencapture所需的格式获取窗口ID
Python
import Quartz
(PyObjC)
ModuleNotFoundError
系统Python未安装PyObjC;请勿尝试安装——改用Swift
osascript
window id
Wrong format返回的是AppleScript窗口索引,而非
screencapture -l
所需的CGWindowID

Supported Applications

支持的应用

ApplicationWindow IDAppleScript ControlNotes
Microsoft ExcelSwiftFull (zoom, scroll, select, activate sheet)Best supported
Google ChromeSwiftBasic (activate, window management)No scroll/zoom via AppleScript
Any macOS appSwiftBasic (activate via
tell application
)
screencapture works universally
AppleScript control depth varies by application. Excel has the richest AppleScript dictionary. For apps with limited AppleScript, use keyboard simulation via
System Events
as a fallback.
应用窗口ID获取AppleScript控制说明
Microsoft ExcelSwift完整支持(缩放、滚动、选择、激活工作表)支持度最佳
Google ChromeSwift基础支持(激活、窗口管理)无法通过AppleScript实现滚动/缩放
任意macOS应用Swift基础支持(通过
tell application
激活)
screencapture工具通用支持
AppleScript的控制深度因应用而异。Excel拥有最丰富的AppleScript字典。对于AppleScript支持有限的应用,可以使用
System Events
模拟键盘操作作为替代方案。