rust-rpa 0.2.2-beta.1 → 0.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +132 -331
  2. package/index.d.ts +108 -18
  3. package/package.json +5 -7
package/README.md CHANGED
@@ -174,305 +174,143 @@ async function main() {
174
174
  main();
175
175
  ```
176
176
 
177
- ## API
177
+ ## API 文档
178
+
179
+ 完整的 TypeScript 类型定义请参考 `index.d.ts` 文件。
178
180
 
179
181
  ### Window 类
180
182
 
181
183
  窗口管理类。
182
184
 
183
- #### 静态方法
184
-
185
- **`Window.all(): Window[]`**
186
-
187
- 获取所有可见窗口列表。
188
-
189
- ```javascript
190
- const windows = Window.all();
191
- ```
192
-
193
- #### 实例方法
194
-
195
- - `id(): number` - 获取窗口 ID
196
- - `pid(): number` - 获取窗口进程 ID
197
- - `parentId(): number` - 获取窗口所属进程的父进程 ID
198
- - `title(): string` - 获取窗口标题
199
- - `appName(): string` - 获取应用程序名称
200
- - `x(): number` - 获取窗口 X 坐标
201
- - `y(): number` - 获取窗口 Y 坐标
202
- - `width(): number` - 获取窗口宽度
203
- - `height(): number` - 获取窗口高度
204
- - `getSize(): WindowSize` - 获取窗口尺寸(宽度和高度)
205
- - `isMinimized(): boolean` - 是否最小化
206
- - `isMaximized(): boolean` - 是否最大化
207
- - `isFocused(): boolean` - 是否聚焦
208
- - `bringToFront(): Promise<void>` - 将窗口置于最前(激活并置顶)
209
- - `maximize(): Promise<void>` - 最大化窗口
210
- - `minimize(): Promise<void>` - 最小化窗口
211
- - `currentMonitor(): Monitor` - 获取窗口所在显示器
212
- - `currentMonitorId(): number` - 获取窗口所在显示器的 ID
213
- - `getBounds(): WindowBounds` - 获取窗口边界(位置和大小)
214
- - `setBounds(bounds): Promise<void>` - 设置窗口边界(位置和大小)
215
- - `toJSON(): WindowToJson` - 转为 JSON 可序列化对象
216
- - `captureImage(options?: CaptureImageOptions): Promise<ImageData>` - 截取窗口图像;可选 `options.size` 指定目标宽高并自动缩放;`options.from` 为 `'screen'` 时截取窗口所在显示器整屏;`options.region` 指定仅截取逻辑像素区域;`options.autoSize` 默认为 `true`,在 Windows 高 DPI 下自动缩放到逻辑像素尺寸
217
- - `findIcon(template, options?): Promise<MatchResult | null>` - 在窗口截图中查找模板图标(先截图 autoSize=true,再执行模板匹配),找到返回 MatchResult,未找到返回 null
218
- - `recognizeText(): Promise<TextRecognitionResult[]>` - 识别窗口截图中的文字(先截图 autoSize=true,再执行 OCR)
219
- - `findText(text, options?): Promise<TextRecognitionResult | null>` - 在窗口截图中查找指定文字,找到返回位置信息,未找到返回 null(先截图 autoSize=true,再执行 OCR);`options.regions` 可指定查找区域列表以提升性能;`options.notText` 可排除同一行中包含特定文字的匹配结果
220
- - `waitText(text, options?): Promise<TextRecognitionResult>` - 等待指定文字出现,超时抛出错误;`options.timeout` 指定等待时间(默认 3000ms),`options.regions` 可指定查找区域,`options.notText` 可排除同一行中包含特定文字的匹配结果
221
- - `waitIcon(template, options?): Promise<MatchResult>` - 等待指定图标出现,超时抛出错误;`options.timeout` 指定等待时间(默认 3000ms),`options.regions` 可指定查找区域,`options.threshold` 可指定匹配阈值(默认 0.8)
222
- - `clickText(text, options?): Promise<ClickResult>` - 点击指定文字,先等待文字出现,然后点击文字中心点;返回点击坐标 `{x, y, relX, relY}`;`options.notText` 可排除同一行中包含特定文字的匹配结果
223
- - `clickIcon(template, options?): Promise<ClickResult>` - 点击指定图标,先等待图标出现,然后点击图标中心点;返回点击坐标 `{x, y, relX, relY}`;`options.threshold` 可指定匹配阈值(默认 0.8)
185
+ **静态方法:**
186
+ - `Window.all(): Window[]` - 获取所有可见窗口
187
+
188
+ **实例方法:**
189
+ - `id(): number` - 窗口 ID
190
+ - `pid(): number` - 进程 ID
191
+ - `parentId(): number` - 父进程 ID
192
+ - `title(): string` - 窗口标题
193
+ - `appName(): string` - 应用程序名称
194
+ - `x(), y(), width(), height()` - 位置和尺寸
195
+ - `getSize(): { width, height }` - 窗口尺寸
196
+ - `isMinimized(), isMaximized(), isFocused()` - 窗口状态
197
+ - `bringToFront()` - 置顶窗口
198
+ - `maximize(), minimize()` - 最大化/最小化
199
+ - `currentMonitor(): Monitor` - 获取所在显示器
200
+ - `currentMonitorId(): number` - 显示器 ID
201
+ - `getBounds(): { x, y, width, height }` - 窗口边界
202
+ - `setBounds(bounds)` - 设置窗口边界
203
+ - `toJSON()` - 转为 JSON 对象
204
+ - `captureImage(options?)` - 截图
205
+ - `recognizeText(options?)` - OCR 识别文字
206
+ - `findText(text, options?)` - 查找文字
207
+ - `findIcon(template, options?)` - 查找图标
208
+ - `waitText(text, options?)` - 等待文字出现
209
+ - `waitIcon(template, options?)` - 等待图标出现
210
+ - `clickText(text, options?)` - 点击文字
211
+ - `clickIcon(template, options?)` - 点击图标
212
+
213
+ **Window 专属 Options:**
214
+ - `from?: 'window' | 'screen'` - 截图来源(`'window'` 默认截窗口,`'screen'` 截整屏)
224
215
 
225
216
  ### Monitor 类
226
217
 
227
218
  显示器管理类。
228
219
 
229
- #### 静态方法
230
-
231
- **`Monitor.all(): Monitor[]`**
232
-
233
- 获取所有显示器列表。
234
-
235
- ```javascript
236
- const monitors = Monitor.all();
237
- const primary = monitors.find(m => m.isPrimary());
238
- ```
239
-
240
- #### 实例方法
220
+ **静态方法:**
221
+ - `Monitor.all(): Monitor[]` - 获取所有显示器
241
222
 
242
- - `id(): number` - 获取显示器 ID
243
- - `name(): string` - 获取显示器名称
244
- - `x(): number` - 获取显示器 X 坐标
245
- - `y(): number` - 获取显示器 Y 坐标
246
- - `width(): number` - 获取显示器宽度
247
- - `height(): number` - 获取显示器高度
248
- - `scaleFactor(): number` - 获取缩放因子
223
+ **实例方法:**
224
+ - `id(): number` - 显示器 ID
225
+ - `name(): string` - 显示器名称
226
+ - `x(), y(), width(), height()` - 位置和尺寸
227
+ - `scaleFactor(): number` - 缩放因子
249
228
  - `isPrimary(): boolean` - 是否主显示器
250
- - `captureImage(options?: CaptureImageOptions): Promise<ImageData>` - 截取显示器图像;可选 `options.size` 指定目标宽高并自动缩放;`options.autoSize` 默认为 `true`,在 Windows 高 DPI 下自动缩放到逻辑像素尺寸
251
- - `findIcon(template, options?): Promise<MatchResult | null>` - 在显示器截图中查找模板图标(先截图 autoSize=true,再执行模板匹配),找到返回 MatchResult,未找到返回 null
252
- - `recognizeText(): Promise<TextRecognitionResult[]>` - 识别显示器截图中的文字(先截图 autoSize=true,再执行 OCR)
253
- - `findText(text, options?): Promise<TextRecognitionResult | null>` - 在显示器截图中查找指定文字,找到返回位置信息,未找到返回 null(先截图 autoSize=true,再执行 OCR);`options.regions` 可指定查找区域列表以提升性能;`options.notText` 可排除同一行中包含特定文字的匹配结果
254
- - `waitText(text, options?): Promise<TextRecognitionResult>` - 等待指定文字出现,超时抛出错误;`options.timeout` 指定等待时间(默认 3000ms),`options.regions` 可指定查找区域,`options.notText` 可排除同一行中包含特定文字的匹配结果
255
- - `waitIcon(template, options?): Promise<MatchResult>` - 等待指定图标出现,超时抛出错误;`options.timeout` 指定等待时间(默认 3000ms),`options.regions` 可指定查找区域,`options.threshold` 可指定匹配阈值(默认 0.8)
256
- - `clickText(text, options?): Promise<ClickResult>` - 点击指定文字,先等待文字出现,然后点击文字中心点;返回点击坐标 `{x, y, relX, relY}`;`options.notText` 可排除同一行中包含特定文字的匹配结果
257
- - `clickIcon(template, options?): Promise<ClickResult>` - 点击指定图标,先等待图标出现,然后点击图标中心点;返回点击坐标 `{x, y, relX, relY}`;`options.threshold` 可指定匹配阈值(默认 0.8)
229
+ - `captureImage(options?)` - 截图
230
+ - `recognizeText(options?)` - OCR 识别文字
231
+ - `findText(text, options?)` - 查找文字
232
+ - `findIcon(template, options?)` - 查找图标
233
+ - `waitText(text, options?)` - 等待文字出现
234
+ - `waitIcon(template, options?)` - 等待图标出现
235
+ - `clickText(text, options?)` - 点击文字
236
+ - `clickIcon(template, options?)` - 点击图标
258
237
 
259
238
  ### ImageData 类
260
239
 
261
- 图像数据类,用于截图和图像处理操作。
262
-
263
- #### 静态工厂方法
264
-
265
- - `ImageData.fromFile(filePath): Promise<ImageData>` - 从文件加载图片
266
- - `ImageData.fromBuffer(buffer): Promise<ImageData>` - 从 Buffer 解码图片
267
-
268
- #### 属性
269
-
270
- - `width: number` - 图像宽度(只读)
271
- - `height: number` - 图像高度(只读)
272
-
273
- #### 方法
274
-
275
- **格式转换与保存**
240
+ 图像处理类。
276
241
 
277
- - `toPng(): Promise<Buffer>` - 转换为 PNG 格式
278
- - `toJpeg(): Promise<Buffer>` - 转换为 JPEG 格式
279
- - `toBmp(): Promise<Buffer>` - 转换为 BMP 格式
280
- - `toFile(filePath): Promise<void>` - 保存到文件(根据扩展名自动识别格式:.png/.jpg/.jpeg/.bmp)
242
+ **静态方法:**
243
+ - `ImageData.fromFile(filePath)` - 从文件加载
244
+ - `ImageData.fromBuffer(buffer)` - Buffer 解码
281
245
 
282
- **图像处理**
283
-
284
- - `crop(x, y, width, height): Promise<ImageData>` - 裁剪图像
285
- - `resize(width, height): Promise<ImageData>` - 缩放图像
286
- - `grayscale(): Promise<ImageData>` - 转换为灰度图
287
- - `findIcon(template, options?): Promise<MatchResult | null>` - 查找模板图标,找到返回 MatchResult,未找到返回 null
288
- - `recognizeText(options?): Promise<TextRecognitionResult[]>` - 识别图片中的文字;`options.regions` 可指定识别区域列表
289
- - `findText(text, options?): Promise<TextRecognitionResult | null>` - 查找指定文字;`options.regions` 可指定查找区域列表;`options.notText` 可排除同一行中包含特定文字的匹配结果
290
-
291
- **数据访问**
246
+ **属性:**
247
+ - `width: number` - 图像宽度
248
+ - `height: number` - 图像高度
292
249
 
250
+ **方法:**
251
+ - `toPng(), toJpeg(), toBmp()` - 格式转换
252
+ - `toFile(filePath)` - 保存到文件
253
+ - `crop(x, y, width, height)` - 裁剪
254
+ - `resize(width, height)` - 缩放
255
+ - `grayscale()` - 灰度化
293
256
  - `getRawData(): Buffer` - 获取原始像素数据
294
- - `metadata(): ImageMetadata` - 获取图片元信息
295
-
296
- **findIcon 参数:**
297
- - `template: ImageData` - 模板图片(要查找的图标)
298
- - `options?: MatchOptions` - 可选的匹配选项对象
299
- - `threshold?: number` - 匹配阈值 (0.0-1.0),默认 0.8
300
- - `regions?: Array<{x, y, width, height}>` - 可选的搜索区域列表,默认为空(全图搜索)
301
- - 区域可超出图片边界,会自动裁剪为与图片的交集范围进行查找
302
-
303
- **MatchOptions 说明:**
304
-
305
- 1. **threshold(匹配阈值)**
306
- - 取值范围:0.0 - 1.0
307
- - 默认值:0.8
308
- - 说明:相似度分数必须大于此阈值才算匹配成功
309
- - 建议:0.8 是个好的起点,根据实际效果调整
310
-
311
- 2. **regions(搜索区域)**
312
- - 格式:`[{x: number, y: number, width: number, height: number}]`
313
- - 默认:空数组(全图搜索)
314
- - 说明:限定在指定区域内搜索,可提高效率和准确性
315
- - 示例:`[{x: 0, y: 0, width: 100, height: 100}]`
316
-
317
- **使用建议:**
318
- - 大多数情况使用默认参数即可:`findIcon(template)`
319
- - 需要调整灵敏度时指定阈值:`findIcon(template, { threshold: 0.9 })`
320
- - 在特定区域查找可提高性能:`findIcon(template, { threshold: 0.8, regions: [...] })`
321
- - **返回值处理**:未找到时返回 `null`,使用时需检查返回值
322
- ```javascript
323
- const result = await image.findIcon(template);
324
- if (result) {
325
- console.log(`找到图标: (${result.x}, ${result.y})`);
326
- } else {
327
- console.log('未找到图标');
328
- }
329
- ```
330
-
331
- **MatchResult 类型:**
332
- ```typescript
333
- interface MatchResult {
334
- found: boolean; // 是否找到匹配
335
- score: number; // 相似度分数 (0.0-1.0)
336
- x: number; // 匹配位置 x 坐标(逻辑屏幕坐标,可直接用于 Mouse.moveTo)
337
- y: number; // 匹配位置 y 坐标(逻辑屏幕坐标,可直接用于 Mouse.moveTo)
338
- width: number; // 模板宽度
339
- height: number; // 模板高度
340
- relX: number; // 相对于当前窗口/屏幕左上角的 x 坐标
341
- relY: number; // 相对于当前窗口/屏幕左上角的 y 坐标
342
- }
343
- ```
344
-
345
- **ImageMetadata 类型:**
346
- ```typescript
347
- interface ImageMetadata {
348
- width: number; // 图片宽度
349
- height: number; // 图片高度
350
- channels: number; // 通道数(固定为 4,RGBA)
351
- bytesPerPixel: number; // 每像素字节数(固定为 4)
352
- dataSize: number; // 数据总字节数
353
- }
354
- ```
355
-
356
- **captureImage 选项(Monitor / Window):**
357
- ```typescript
358
- // 截取区域(逻辑像素),仅对 Window.captureImage 有效
359
- interface CaptureRegion {
360
- x: number; // 区域左上角 x(相对截图画布左上角)
361
- y: number; // 区域左上角 y
362
- width: number; // 区域宽度
363
- height: number; // 区域高度
364
- }
365
-
366
- interface CaptureImageOptions {
367
- size?: { width: number; height: number }; // 可选,截取后缩放到指定宽高
368
- // 以下仅对 Window.captureImage 有效:
369
- from?: 'window' | 'screen'; // 默认 'window' 截窗口;'screen' 截窗口所在显示器整屏(可配合 getBounds 与 image.crop 裁剪出窗口)
370
- region?: CaptureRegion | null; // 仅截取该逻辑像素区域,不填则截全图
371
- autoSize?: boolean | null; // 默认为 true,在 Windows 存在 DPI 缩放时自动将图像缩放到逻辑像素宽高(与 getSize/getBounds 一致)
372
- }
373
- ```
257
+ - `metadata()` - 获取图片元信息
258
+ - `recognizeText(options?)` - OCR 识别文字
259
+ - `findText(text, options?)` - 查找文字
260
+ - `findIcon(template, options?)` - 模板匹配
374
261
 
375
262
  ### Mouse 类
376
263
 
377
- 鼠标控制类,所有方法都是静态的。
264
+ 鼠标控制类(静态方法)。
378
265
 
379
- #### 静态方法
380
-
381
- - `Mouse.moveTo(x, y, duration?): Promise<void>` - 移动鼠标到指定坐标。**duration** 可选,移动动画持续时间(秒),默认为 0(瞬间移动)。如果设置 > 0,鼠标将以平滑动画的方式移动到目标点,动画过程中会触发 mouseMove 事件
382
- - `Mouse.moveRel(dx, dy, duration?): Promise<void>` - 相对移动鼠标。**dx** X 轴偏移量(正数向右,负数向左);**dy** Y 轴偏移量(正数向下,负数向上);**duration** 可选,移动动画持续时间(秒),默认为 0
383
- - `Mouse.click(button?): Promise<void>` - 点击鼠标。**button** 可选,可用枚举 `MouseButton.Left` / `MouseButton.Right` 或字符串 `'left'` / `'right'` 等,默认左键
384
- - `Mouse.doubleClick(button?): Promise<void>` - 双击鼠标,button 同上
385
- - `Mouse.down(button?): Promise<void>` - 按下鼠标按钮,button 同上
386
- - `Mouse.up(button?): Promise<void>` - 释放鼠标按钮,button 同上
387
- - **MouseButton** 枚举:`MouseButton.Left` | `Right` | `Middle` | `Back` | `Forward`,用于上述 button 参数
388
- - `Mouse.scroll(deltaX?, deltaY?): Promise<void>` - 滚动鼠标滚轮。**方向**:`deltaY` 正数向上、负数向下;`deltaX` 正数向右、负数向左。如 `scroll(0, 3)` 向上滚、`scroll(0, -3)` 向下滚
389
- - `Mouse.position(): Promise<{ x: number, y: number }>` - 获取当前鼠标位置
266
+ - `Mouse.moveTo(x, y, duration?)` - 移动到坐标(duration 动画时间,秒)
267
+ - `Mouse.moveRel(dx, dy, duration?)` - 相对移动
268
+ - `Mouse.click(button?)` - 点击(`'left'`, `'right'`, `'middle'`)
269
+ - `Mouse.doubleClick(button?)` - 双击
270
+ - `Mouse.down(button?), Mouse.up(button?)` - 按下/释放
271
+ - `Mouse.scroll(deltaX?, deltaY?)` - 滚动(Y 正数向上、负数向下)
272
+ - `Mouse.position()` - 获取当前位置
390
273
 
391
274
  ### Keyboard 类
392
275
 
393
- 键盘控制类,所有方法都是静态的。
394
-
395
- #### 静态方法
276
+ 键盘控制类(静态方法)。
396
277
 
397
- - `Keyboard.typeText(text): Promise<void>` - 输入文本
398
- - `Keyboard.click(key): Promise<void>` - 按下并释放按键
399
- - `Keyboard.down(key): Promise<void>` - 按下按键
400
- - `Keyboard.up(key): Promise<void>` - 释放按键
401
- - `Keyboard.sequence(keys): Promise<void>` - 按键序列(如 `[Key.Ctrl, Key.C]`)
278
+ - `Keyboard.typeText(text)` - 输入文本
279
+ - `Keyboard.click(key)` - 按下并释放按键
280
+ - `Keyboard.down(key), Keyboard.up(key)` - 按下/释放
281
+ - `Keyboard.sequence(keys)` - 按键序列(如 `[Key.Ctrl, Key.C]`)
402
282
 
403
- **key 参数**:可使用 **Key** 枚举(如 `Key.Enter`、`Key.Ctrl`、`Key.F1`)或字符串(如 `'enter'`、`'ctrl'`)。**Key** 提供字母 A–Z、数字 Num0–Num9、功能键 F1–F12、修饰键 Control/Ctrl/Shift/Alt/Meta/Command/Win、控制键 Enter/Escape/Tab/Space/Backspace/Delete/Insert、方向键 Left/Right/Up/Down、Home/End/PageUp/PageDown、数字键盘 Numpad0–Numpad9、NumpadAdd/NumpadEnter 等。
283
+ **Key 枚举:**`Key.Enter`, `Key.Ctrl`, `Key.F1`, `Key.A`
404
284
 
405
285
  ### Clipboard 类
406
286
 
407
- 剪贴板控制类,所有方法都是静态的。
287
+ 剪贴板控制类(静态方法)。
408
288
 
409
- #### 静态方法
410
-
411
- - `Clipboard.readText(): Promise<string>` - 读取剪贴板文本内容
412
- - `Clipboard.writeText(text): Promise<void>` - 将文本写入剪贴板
413
- - `Clipboard.writeImage(source): Promise<void>` - 将图片写入剪贴板,`source` 支持文件路径(string)、base64 字符串、data URI 或 Buffer
414
- - `Clipboard.writeFile(paths): Promise<void>` - 将文件路径写入剪贴板,粘贴时在资源管理器/访达中为文件(`paths` 可为单个路径字符串或路径数组)
415
- - `Clipboard.paste(): Promise<void>` - 执行粘贴操作(使用 Cmd/Ctrl+V 快捷键)
416
- - `Clipboard.pasteText(text): Promise<void>` - 将文本写入剪贴板并粘贴,完成后自动恢复剪贴板原始内容
417
- - `Clipboard.pasteImage(source): Promise<void>` - 将图片写入剪贴板并粘贴,完成后自动恢复剪贴板原始内容(`source` 同 `writeImage`)
418
- - `Clipboard.pasteFile(paths): Promise<void>` - 将文件路径写入剪贴板并粘贴,不会自动恢复剪贴板原始内容
289
+ - `Clipboard.readText()` - 读取剪贴板文本
290
+ - `Clipboard.writeText(text)` - 写入文本
291
+ - `Clipboard.writeImage(source)` - 写入图片(支持文件路径、base64、Buffer)
292
+ - `Clipboard.writeFile(paths)` - 写入文件路径
293
+ - `Clipboard.paste()` - 执行粘贴
294
+ - `Clipboard.pasteText(text)` - 写入并粘贴(自动恢复剪贴板)
295
+ - `Clipboard.pasteImage(source)` - 写入图片并粘贴(自动恢复)
296
+ - `Clipboard.pasteFile(paths)` - 写入文件路径并粘贴
419
297
 
420
298
  ### Permission 类
421
299
 
422
- 权限检查工具类,所有方法都是静态的。
300
+ 权限检查类(静态方法)。
423
301
 
424
- #### 静态方法
302
+ - `Permission.checkAccessibility(prompt?)` - 检查辅助功能权限
303
+ - `Permission.checkScreenCapture(prompt?)` - 检查屏幕录制权限
425
304
 
426
- - `Permission.checkAccessibility(prompt?): boolean` - 检查辅助功能权限(鼠标、键盘、窗口操作等需要此权限)
427
- - `Permission.checkScreenCapture(prompt?): boolean` - 检查屏幕录制权限(截图功能需要此权限)
305
+ **说明:**`prompt` 默认为 `true`,无权限时自动弹出系统授权对话框(仅 macOS)
428
306
 
429
307
  ### pause 函数
430
308
 
431
- 暂停/等待指定时间的辅助函数。
432
-
433
- #### 函数签名
434
-
435
- - `pause(ms: number): Promise<void>` - 等待指定毫秒数
309
+ - `pause(ms)` - 等待指定毫秒数
436
310
 
437
311
  ```javascript
438
312
  const { pause } = require('rust-rpa');
439
-
440
- // 等待 1 秒
441
- await pause(1000);
442
-
443
- // 在操作之间添加延迟
444
- await Mouse.click('left');
445
- await pause(500); // 等待 500ms
446
- await Keyboard.typeText('Hello');
447
- ```
448
-
449
- **参数说明:**
450
- - `ms`:等待时间,单位为毫秒
451
-
452
- ---
453
-
454
- **Permission 类参数说明:**
455
- - `prompt`(可选,默认 `true`):无权限时是否自动弹出系统授权对话框(仅 macOS 生效)
456
-
457
- **平台行为差异:**
458
-
459
- | 平台 | checkAccessibility | checkScreenCapture |
460
- |------|--------------------|--------------------|
461
- | macOS | 调用 `AXIsProcessTrustedWithOptions`,prompt=true 时弹出辅助功能授权对话框 | 调用 `CGRequestScreenCaptureAccess`,prompt=true 时弹出屏幕录制授权对话框 |
462
- | Windows | 检查是否以管理员身份运行(管理员即有权限) | 检查是否以管理员身份运行 |
463
-
464
- ```javascript
465
- const { Permission } = require('rust-rpa');
466
-
467
- // 检查并弹出授权(推荐在应用启动时调用)
468
- const hasAccessibility = Permission.checkAccessibility();
469
- const hasScreenCapture = Permission.checkScreenCapture();
470
-
471
- console.log('辅助功能权限:', hasAccessibility);
472
- console.log('屏幕录制权限:', hasScreenCapture);
473
-
474
- // 仅检查,不弹窗
475
- const check = Permission.checkAccessibility(false);
313
+ await pause(1000); // 等待 1 秒
476
314
  ```
477
315
 
478
316
  ## macOS 权限要求
@@ -716,48 +554,20 @@ if (targetWindow) {
716
554
  // clickText 也支持 notText 参数
717
555
  const clickResult = await targetWindow.clickText('发送', { notText: '草稿', timeout: 5000 });
718
556
  console.log(`点击位置: (${clickResult.x}, ${clickResult.y})`);
719
- }
720
- ```
721
-
722
- **TextRecognitionResult 类型:**
723
- ```typescript
724
- interface TextRecognitionResult {
725
- text: string; // 识别到的文字
726
- x: number; // 文字区块左上角 x 坐标(逻辑屏幕坐标,可直接用于 Mouse.moveTo)
727
- y: number; // 文字区块左上角 y 坐标(逻辑屏幕坐标,可直接用于 Mouse.moveTo)
728
- width: number; // 文字区块宽度(像素)
729
- height: number; // 文字区块高度(像素)
730
- confidence: number; // 置信度(0.0-1.0)
731
- relX: number; // 相对于当前窗口/屏幕左上角的 x 坐标
732
- relY: number; // 相对于当前窗口/屏幕左上角的 y 坐标
733
- }
734
- ```
735
-
736
- **ClickResult 类型:**
737
- ```typescript
738
- interface ClickResult {
739
- x: number; // 点击的 x 坐标(屏幕坐标)
740
- y: number; // 点击的 y 坐标(屏幕坐标)
741
- relX: number; // 相对于当前窗口/屏幕左上角的 x 坐标
742
- relY: number; // 相对于当前窗口/屏幕左上角的 y 坐标
743
- }
744
- ```
745
-
746
- **FindTextOptions 类型:**
747
- ```typescript
748
- interface FindTextOptions {
749
- regions?: Array<{ x: number, y: number, width: number, height: number }>; // 查找区域列表
750
- notText?: string; // 排除文字,若同一行中包含此文字则排除该匹配结果
751
- }
752
- ```
753
-
754
- **WaitOptions 类型:**
755
- ```typescript
756
- interface WaitOptions {
757
- regions?: Array<{ x: number, y: number, width: number, height: number }>; // 查找区域列表
758
- timeout?: number; // 等待超时时间(毫秒),默认 3000
759
- threshold?: number; // 匹配阈值(仅用于 waitIcon/clickIcon),默认 0.8
760
- notText?: string; // 排除文字(仅用于 waitText/clickText)
557
+
558
+ // 使用 from 参数指定截图来源('window' 默认截窗口,'screen' 截窗口所在显示器整屏)
559
+ // 场景:窗口被其他窗口遮挡时,从屏幕截图可以获取更完整的内容
560
+ const screenResult = await targetWindow.findText('提示', { from: 'screen' });
561
+ if (screenResult) {
562
+ console.log(`在屏幕截图中找到"提示": (${screenResult.x}, ${screenResult.y})`);
563
+ }
564
+
565
+ // recognizeText waitText 同样支持 from 参数
566
+ const screenTexts = await targetWindow.recognizeText({ from: 'screen' });
567
+ console.log(`屏幕截图中识别到 ${screenTexts.length} 条文字`);
568
+
569
+ const waitResult = await targetWindow.waitText('加载完成', { from: 'screen', timeout: 10000 });
570
+ console.log(`等待到文字出现: (${waitResult.x}, ${waitResult.y})`);
761
571
  }
762
572
  ```
763
573
 
@@ -771,51 +581,42 @@ interface WaitOptions {
771
581
  | macOS | ARM64 (Apple Silicon) | ✅ 支持 | 需要辅助功能权限 |
772
582
  | Linux | 全部 | ❌ 不支持 | 当前版本无计划 |
773
583
 
774
- ## 性能
775
-
776
- - 窗口枚举通常在 < 100ms 内完成
777
- - 异步操作不会阻塞 Node.js 事件循环
778
- - 最小的内存开销
779
-
780
584
  ## 开发
781
585
 
782
586
  从源码构建和开发指南请参阅 [dev.md](./dev.md)。
783
587
 
784
- ## 路线图
785
-
786
- - [x] 窗口枚举和信息获取(基于 XCap)
787
- - [x] 鼠标和键盘自动化(Mouse/Keyboard 类)
788
- - [x] 屏幕截图(Monitor/Window 截图)
789
- - [x] 多显示器支持
790
- - [x] 图像格式转换(PNG/JPEG/BMP)
791
- - [x] 图像裁剪功能
792
- - [x] 图像缩放功能(Lanczos3 高质量算法)
793
- - [x] 图像识别(模板匹配)
794
- - [x] 图像灰度化
795
- - [x] 图像数据访问(原始像素、元信息)
796
- - [x] 图像保存到文件
797
- - [x] 剪贴板操作
798
- - [x] 窗口操作(置顶、移动、调整大小、父进程查询)
799
- - [x] 窗口最大化/最小化
800
- - [x] OCR 文字识别(基于 PP-OCRv5_mobile)
801
- - [x] 文字位置查找(findText)
802
- - [x] 等待文字、图标出现(waitText/waitIcon)
803
- - [x] 点击文字、图标(clickText/clickIcon)
804
- - [ ] 进程管理
805
-
806
588
  ## 更新日志
807
589
 
590
+ ### 0.2.3
591
+
592
+ #### 修复
593
+
594
+ - **OCR `recognizeText` 多区域识别修复**: 修复了 `recognizeText` 在指定多个 `regions` 时坐标转换错误的问题
595
+
808
596
  ### 0.2.2
809
- - **findText|waitText|clickText**匹配文字时,模糊匹配,例如o和0避免ocr识别不一致造成无法查找或者点击
810
597
 
811
598
  #### 新功能
812
599
 
600
+ - **Window 文字和图标操作新增 `from` 参数**: `findText`、`waitText`、`clickText`、`recognizeText`、`findIcon`、`waitIcon`、`clickIcon` 方法新增 `from` 选项,用于指定截图来源
601
+ - `from: 'window'`(默认)- 截取当前窗口内容
602
+ - `from: 'screen'` - 截取窗口所在显示器的整屏内容
603
+ - 适用场景:窗口被其他窗口遮挡时,从屏幕截图可以获取更完整的内容
604
+ - 示例:`window.findText('提示', { from: 'screen' })`、`window.waitIcon(template, { from: 'screen' })`
605
+
606
+ #### 类型定义更新
607
+
608
+ - **Options 类型分离**: 为 `Window` 和 `Monitor` 类分别定义独立的 Options 类型,使 API 更清晰
609
+ - `WindowMatchOptions` / `MonitorMatchOptions` / `MatchOptionsJs` - 分别用于 `findIcon`
610
+ - `WindowFindTextOptions` / `MonitorFindTextOptions` / `FindTextOptions` - 分别用于 `findText`
611
+ - `WindowRecognizeTextOptions` / `MonitorRecognizeTextOptions` / `RecognizeTextOptions` - 分别用于 `recognizeText`
612
+ - `WindowWaitOptions` / `MonitorWaitOptions` / `WaitOptions` - 分别用于 `waitText` / `waitIcon` / `clickText` / `clickIcon`
613
+ - 只有 Window 专用类型包含 `from` 参数,Monitor 类型不包含(因为 Monitor 本身就是屏幕)
614
+
615
+ #### 其他改进
616
+
617
+ - **findText|waitText|clickText** 匹配文字时,模糊匹配,例如 o 和 0 避免 OCR 识别不一致造成无法查找或者点击
813
618
  - **Window.maximize()**: 最大化窗口
814
- - Windows 平台:使用 `ShowWindow(hwnd, SW_MAXIMIZE)` Win32 API
815
- - macOS 平台:使用 AppleScript 点击窗口菜单中的"缩放"或"Zoom"菜单项
816
619
  - **Window.minimize()**: 最小化窗口
817
- - Windows 平台:使用 `ShowWindow(hwnd, SW_MINIMIZE)` Win32 API
818
- - macOS 平台:使用 AppleScript 点击窗口菜单中的"最小化"或"Minimize"菜单项
819
620
 
820
621
 
821
622
  ### 0.2.1
package/index.d.ts CHANGED
@@ -27,26 +27,110 @@ export interface ImageMetadata {
27
27
  /** 数据总字节数 */
28
28
  dataSize: number
29
29
  }
30
- /** 匹配选项 */
30
+ /** 匹配选项(ImageData 使用) */
31
31
  export interface MatchOptionsJs {
32
32
  /** 匹配阈值 (0.0-1.0),低于此值视为未找到,默认 0.8 */
33
33
  threshold?: number
34
34
  /** 匹配区域列表,若为空则在整个图片中匹配 */
35
35
  regions?: Array<MatchRegion>
36
36
  }
37
- /** 文字查找选项 */
37
+ /** 匹配选项(Window 专用) */
38
+ export interface WindowMatchOptions {
39
+ /** 匹配阈值 (0.0-1.0),低于此值视为未找到,默认 0.8 */
40
+ threshold?: number
41
+ /** 匹配区域列表,若为空则在整个图片中匹配 */
42
+ regions?: Array<MatchRegion>
43
+ /**
44
+ * 图片来源:
45
+ * - `'window'`(默认):截取当前窗口
46
+ * - `'screen'`:截取窗口所在显示器的整屏
47
+ */
48
+ from?: 'window' | 'screen'
49
+ }
50
+ /** 匹配选项(Monitor 专用) */
51
+ export interface MonitorMatchOptions {
52
+ /** 匹配阈值 (0.0-1.0),低于此值视为未找到,默认 0.8 */
53
+ threshold?: number
54
+ /** 匹配区域列表,若为空则在整个图片中匹配 */
55
+ regions?: Array<MatchRegion>
56
+ }
57
+ /** 文字查找选项(ImageData 使用) */
38
58
  export interface FindTextOptions {
39
59
  /** 查找区域列表,若为空则在全图查找 */
40
60
  regions?: Array<MatchRegion>
41
61
  /** 排除文字,若同一行中包含此文字则排除该匹配结果 */
42
62
  notText?: string
43
63
  }
44
- /** 文字识别选项 */
64
+ /** 文字查找选项(Window 专用) */
65
+ export interface WindowFindTextOptions {
66
+ /** 查找区域列表,若为空则在全图查找 */
67
+ regions?: Array<MatchRegion>
68
+ /** 排除文字,若同一行中包含此文字则排除该匹配结果 */
69
+ notText?: string
70
+ /**
71
+ * 图片来源:
72
+ * - `'window'`(默认):截取当前窗口
73
+ * - `'screen'`:截取窗口所在显示器的整屏
74
+ */
75
+ from?: 'window' | 'screen'
76
+ }
77
+ /** 文字查找选项(Monitor 专用) */
78
+ export interface MonitorFindTextOptions {
79
+ /** 查找区域列表,若为空则在全图查找 */
80
+ regions?: Array<MatchRegion>
81
+ /** 排除文字,若同一行中包含此文字则排除该匹配结果 */
82
+ notText?: string
83
+ }
84
+ /** 文字识别选项(ImageData 使用) */
45
85
  export interface RecognizeTextOptions {
46
86
  /** 识别区域列表,若为空则识别全图 */
47
87
  regions?: Array<MatchRegion>
48
88
  }
49
- /** 等待选项 */
89
+ /** 文字识别选项(Window 专用) */
90
+ export interface WindowRecognizeTextOptions {
91
+ /** 识别区域列表,若为空则识别全图 */
92
+ regions?: Array<MatchRegion>
93
+ /**
94
+ * 图片来源:
95
+ * - `'window'`(默认):截取当前窗口
96
+ * - `'screen'`:截取窗口所在显示器的整屏
97
+ */
98
+ from?: 'window' | 'screen'
99
+ }
100
+ /** 文字识别选项(Monitor 专用) */
101
+ export interface MonitorRecognizeTextOptions {
102
+ /** 识别区域列表,若为空则识别全图 */
103
+ regions?: Array<MatchRegion>
104
+ }
105
+ /** 等待选项(Window 专用) */
106
+ export interface WindowWaitOptions {
107
+ /** 查找区域列表,若为空则在全图查找 */
108
+ regions?: Array<MatchRegion>
109
+ /** 等待超时时间(毫秒),默认 3000 */
110
+ timeout?: number
111
+ /** 匹配阈值 (0.0-1.0),低于此值视为未找到,默认 0.8(仅用于 waitIcon/clickIcon) */
112
+ threshold?: number
113
+ /** 排除文字,若同一行中包含此文字则排除该匹配结果(仅用于 waitText/clickText) */
114
+ notText?: string
115
+ /**
116
+ * 图片来源:
117
+ * - `'window'`(默认):截取当前窗口
118
+ * - `'screen'`:截取窗口所在显示器的整屏
119
+ */
120
+ from?: 'window' | 'screen'
121
+ }
122
+ /** 等待选项(Monitor 专用) */
123
+ export interface MonitorWaitOptions {
124
+ /** 查找区域列表,若为空则在全图查找 */
125
+ regions?: Array<MatchRegion>
126
+ /** 等待超时时间(毫秒),默认 3000 */
127
+ timeout?: number
128
+ /** 匹配阈值 (0.0-1.0),低于此值视为未找到,默认 0.8(仅用于 waitIcon/clickIcon) */
129
+ threshold?: number
130
+ /** 排除文字,若同一行中包含此文字则排除该匹配结果(仅用于 waitText/clickText) */
131
+ notText?: string
132
+ }
133
+ /** 等待选项(兼容旧代码,与 WindowWaitOptions 相同) */
50
134
  export interface WaitOptions {
51
135
  /** 查找区域列表,若为空则在全图查找 */
52
136
  regions?: Array<MatchRegion>
@@ -56,6 +140,12 @@ export interface WaitOptions {
56
140
  threshold?: number
57
141
  /** 排除文字,若同一行中包含此文字则排除该匹配结果(仅用于 waitText/clickText) */
58
142
  notText?: string
143
+ /**
144
+ * 图片来源:
145
+ * - `'window'`(默认):截取当前窗口
146
+ * - `'screen'`:截取窗口所在显示器的整屏
147
+ */
148
+ from?: 'window' | 'screen'
59
149
  }
60
150
  /** 图标匹配结果 */
61
151
  export interface MatchResult {
@@ -570,7 +660,7 @@ export declare class Monitor {
570
660
  * }
571
661
  * ```
572
662
  */
573
- findIcon(template: ImageData, options?: MatchOptionsJs | undefined | null): Promise<MatchResult | null>
663
+ findIcon(template: ImageData, options?: MonitorMatchOptions | undefined | null): Promise<MatchResult | null>
574
664
  /**
575
665
  * 识别显示器截图中的文字(异步)
576
666
  *
@@ -587,7 +677,7 @@ export declare class Monitor {
587
677
  * }
588
678
  * ```
589
679
  */
590
- recognizeText(): Promise<Array<TextRecognitionResult>>
680
+ recognizeText(options?: MonitorRecognizeTextOptions | null): Promise<Array<TextRecognitionResult>>
591
681
  /**
592
682
  * 在显示器截图中查找指定文字(异步)
593
683
  *
@@ -614,7 +704,7 @@ export declare class Monitor {
614
704
  * });
615
705
  * ```
616
706
  */
617
- findText(text: string, options?: FindTextOptions | null): Promise<TextRecognitionResult | null>
707
+ findText(text: string, options?: MonitorFindTextOptions | null): Promise<TextRecognitionResult | null>
618
708
  /**
619
709
  * 等待指定文字出现(异步)
620
710
  *
@@ -650,7 +740,7 @@ export declare class Monitor {
650
740
  * });
651
741
  * ```
652
742
  */
653
- waitText(text: string, options?: WaitOptions | null): Promise<TextRecognitionResult>
743
+ waitText(text: string, options?: MonitorWaitOptions | null): Promise<TextRecognitionResult>
654
744
  /**
655
745
  * 等待指定图标出现(异步)
656
746
  *
@@ -687,7 +777,7 @@ export declare class Monitor {
687
777
  * });
688
778
  * ```
689
779
  */
690
- waitIcon(template: ImageData, options?: WaitOptions | null): Promise<MatchResult>
780
+ waitIcon(template: ImageData, options?: MonitorWaitOptions | null): Promise<MatchResult>
691
781
  /**
692
782
  * 点击指定文字(异步)
693
783
  *
@@ -714,7 +804,7 @@ export declare class Monitor {
714
804
  * });
715
805
  * ```
716
806
  */
717
- clickText(text: string, options?: WaitOptions | null): Promise<ClickResult>
807
+ clickText(text: string, options?: MonitorWaitOptions | null): Promise<ClickResult>
718
808
  /**
719
809
  * 点击指定图标(异步)
720
810
  *
@@ -742,7 +832,7 @@ export declare class Monitor {
742
832
  * });
743
833
  * ```
744
834
  */
745
- clickIcon(template: ImageData, options?: WaitOptions | null): Promise<ClickResult>
835
+ clickIcon(template: ImageData, options?: MonitorWaitOptions | null): Promise<ClickResult>
746
836
  }
747
837
  /**
748
838
  * Window 类 - 封装 XCap 的 Window 对象
@@ -969,7 +1059,7 @@ export declare class Window {
969
1059
  * }
970
1060
  * ```
971
1061
  */
972
- findIcon(template: ImageData, options?: MatchOptionsJs | undefined | null): Promise<MatchResult | null>
1062
+ findIcon(template: ImageData, options?: WindowMatchOptions | undefined | null): Promise<MatchResult | null>
973
1063
  /**
974
1064
  * 识别窗口中的文字(异步)
975
1065
  *
@@ -992,7 +1082,7 @@ export declare class Window {
992
1082
  * }
993
1083
  * ```
994
1084
  */
995
- recognizeText(): Promise<Array<TextRecognitionResult>>
1085
+ recognizeText(options?: WindowRecognizeTextOptions | null): Promise<Array<TextRecognitionResult>>
996
1086
  /**
997
1087
  * 在窗口中查找指定文字(异步)
998
1088
  *
@@ -1025,7 +1115,7 @@ export declare class Window {
1025
1115
  * });
1026
1116
  * ```
1027
1117
  */
1028
- findText(text: string, options?: FindTextOptions | null): Promise<TextRecognitionResult | null>
1118
+ findText(text: string, options?: WindowFindTextOptions | null): Promise<TextRecognitionResult | null>
1029
1119
  /**
1030
1120
  * 等待指定文字出现(异步)
1031
1121
  *
@@ -1062,7 +1152,7 @@ export declare class Window {
1062
1152
  * });
1063
1153
  * ```
1064
1154
  */
1065
- waitText(text: string, options?: WaitOptions | null): Promise<TextRecognitionResult>
1155
+ waitText(text: string, options?: WindowWaitOptions | null): Promise<TextRecognitionResult>
1066
1156
  /**
1067
1157
  * 等待指定图标出现(异步)
1068
1158
  *
@@ -1100,7 +1190,7 @@ export declare class Window {
1100
1190
  * });
1101
1191
  * ```
1102
1192
  */
1103
- waitIcon(template: ImageData, options?: WaitOptions | null): Promise<MatchResult>
1193
+ waitIcon(template: ImageData, options?: WindowWaitOptions | null): Promise<MatchResult>
1104
1194
  /**
1105
1195
  * 点击指定文字(异步)
1106
1196
  *
@@ -1128,7 +1218,7 @@ export declare class Window {
1128
1218
  * });
1129
1219
  * ```
1130
1220
  */
1131
- clickText(text: string, options?: WaitOptions | null): Promise<ClickResult>
1221
+ clickText(text: string, options?: WindowWaitOptions | null): Promise<ClickResult>
1132
1222
  /**
1133
1223
  * 点击指定图标(异步)
1134
1224
  *
@@ -1157,7 +1247,7 @@ export declare class Window {
1157
1247
  * });
1158
1248
  * ```
1159
1249
  */
1160
- clickIcon(template: ImageData, options?: WaitOptions | null): Promise<ClickResult>
1250
+ clickIcon(template: ImageData, options?: WindowWaitOptions | null): Promise<ClickResult>
1161
1251
  }
1162
1252
  /** Clipboard 类 - 剪贴板控制 */
1163
1253
  export declare class Clipboard {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rust-rpa",
3
- "version": "0.2.2-beta.1",
3
+ "version": "0.2.3",
4
4
  "description": "Rust-based RPA automation library for Node.js",
5
5
  "type": "commonjs",
6
6
  "main": "index.js",
@@ -55,8 +55,6 @@
55
55
  },
56
56
  "devDependencies": {
57
57
  "@napi-rs/cli": "^3.5.1",
58
- "node-screenshots": "^0.2.8",
59
- "sharp": "^0.34.5",
60
58
  "vitest": "^4.0.18"
61
59
  },
62
60
  "files": [
@@ -69,9 +67,9 @@
69
67
  "commander": "^14.0.3"
70
68
  },
71
69
  "optionalDependencies": {
72
- "@alibot/rust-rpa-win32-x64-msvc": "0.2.2-beta.1",
73
- "@alibot/rust-rpa-win32-ia32-msvc": "0.2.2-beta.1",
74
- "@alibot/rust-rpa-darwin-x64": "0.2.2-beta.1",
75
- "@alibot/rust-rpa-darwin-arm64": "0.2.2-beta.1"
70
+ "@alibot/rust-rpa-win32-x64-msvc": "0.2.3",
71
+ "@alibot/rust-rpa-win32-ia32-msvc": "0.2.3",
72
+ "@alibot/rust-rpa-darwin-x64": "0.2.3",
73
+ "@alibot/rust-rpa-darwin-arm64": "0.2.3"
76
74
  }
77
75
  }