# ElectronCaptureDemo **Repository Path**: scenario-samples/electron-capture-demo ## Basic Information - **Project Name**: ElectronCaptureDemo - **Description**: 截屏是一些PC聊天应用普遍拥有的一项功能,在应用上实现截全屏和区域截屏等功能。 本示例是通过desktopCapturer获取屏幕源,获得屏幕源中的缩略图来实现全屏截图,通过对缩略图使用nativeImage中的crop方法对其进行裁剪实现区域截屏。 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2025-12-11 - **Last Updated**: 2025-12-11 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 应用截屏 ## 介绍 截屏是一些PC聊天应用普遍拥有的一项功能,在应用上实现截全屏和区域截屏等功能。 本示例是通过[desktopCapturer](https://www.electronjs.org/docs/latest/api/desktop-capturer)获取屏幕源,获得屏幕源中的缩略图来实现全屏截图,通过对缩略图使用[nativeImage](https://www.electronjs.org/docs/latest/api/native-image)中的crop方法对其进行裁剪实现区域截屏。 ## 效果预览 ## 约束与限制 - 本示例支持API Version 17 Release及以上版本。 - 本示例支持HarmonyOS 5.0.5 Release SDK及以上版本。 - 本示例需要使用DevEco Studio 5.0.4 Release及以上版本进行编译运行。 ## 使用说明 1. 点击开始框选截屏,可以对某片区域进行框选,在下面看到截屏效果。 2. 点击全屏截图,截取的全屏图片会在下面看到效果。 3. 点击重置,会清空截图预览。 4. 支持快捷键Ctrl+Shift+A进行框选截屏。 ## 实现思路 1. 实现全屏截图: 方式一:使用[desktopCapturer](https://www.electronjs.org/docs/latest/api/desktop-capturer)获取屏幕源,获得屏幕源中的thumbnail来实现全屏截图。 方式二:通过调用C++调用的系统截图接口编译的node,获取全屏截图图片。 具体代码如下: ``` // 处理全屏截图请求 ipcMain.handle('capture-fullscreen', async (event, api) => { if (api == 'arKtsApi') { let res = await systemPreferences.requestSystemPermission('screen-capture'); if (res) { let ScreenImage = addon.Screenshot(); //调用系统截图接口 let BgraBuffer = rgbaToBGRA(ScreenImage.images[0].buffer, ScreenImage.images[0].width, ScreenImage.images[0].height) const image = nativeImage.createFromBuffer(BgraBuffer, { width: ScreenImage.images[0].width, height: ScreenImage.images[0].height }); return image.toDataURL(); } else { return; } } else { const sources = await desktopCapturer.getSources({ types: ['screen'], thumbnailSize: screen.getPrimaryDisplay().workAreaSize }); return sources[0].thumbnail.toDataURL(); } }); ``` 2. 创建透明全屏子窗口作为截图窗口给用户来选择截图区域,同上边实现全屏截图的两种方式获取到全屏截图,使用nativeImage的[crop](https://www.electronjs.org/docs/latest/api/native-image#imagecroprect)的方法对全屏截图进行截取来实现区域截图,具体代码如下: ``` // 创建截图窗口 function createScreenshotWindow(api) { const displays = screen.getAllDisplays(); const { bounds, workArea } = getTotalScreenBounds(displays); screenshotWindow = new BrowserWindow({ windowInfo: { // type的取值是mainWindow,subWindow,floatWindow // 创建常规子窗,同时parent应设置为父窗口引用 type: 'subWindow' }, parent: mainWindow, x: bounds.x, y: bounds.y, width: bounds.width, height: bounds.height, transparent: true, frame: false, alwaysOnTop: true, skipTaskbar: true, resizable: false, enableLargerThanScreen: true, webPreferences: { nodeIntegration: true, contextIsolation: false } }); screenshotWindow.setFullScreen(true); if (api == 'arKtsApi') { screenshotWindow.loadFile(path.join(__dirname, 'renderer/screenshotArkTSAPI.html')); } else { screenshotWindow.loadFile(path.join(__dirname, 'renderer/screenshotElectronAPI.html')); } screenshotWindow.setIgnoreMouseEvents(false); // 确保窗口在所有屏幕上都可见 screenshotWindow.setAlwaysOnTop(true, 'screen-saver'); // screenshotWindow.webContents.openDevTools(); screenshotWindow.on('closed', () => { screenshotWindow = null; }); return screenshotWindow; } // 处理区域截图请求 ipcMain.handle('capture-region', async (event, rect) => { try { let image; if (rect.api == 'arKtsApi') { // 调用系统api截图 let res = await systemPreferences.requestSystemPermission('screen-capture'); if (res) { let ScreenImage = addon.Screenshot(); //调用截图接口 let BgraBuffer = rgbaToBGRA(ScreenImage.images[0].buffer, ScreenImage.images[0].width, ScreenImage.images[0].height) const imageBuffer = nativeImage.createFromBuffer(BgraBuffer, { width: ScreenImage.images[0].width, height: ScreenImage.images[0].height }); image = nativeImage.createFromDataURL(imageBuffer.toDataURL()); } else { return; } } else { // 调用electron api截图 const sources = await desktopCapturer.getSources({ types: ['screen'], thumbnailSize: screen.getPrimaryDisplay().workAreaSize }); image = nativeImage.createFromDataURL(sources[0].thumbnail.toDataURL()); } const imageSize = image.getSize(); const display = screen.getAllDisplays()[0] const displayBounds = display.bounds; const sourceScaleX = imageSize.width / displayBounds.width; const sourceScaleY = imageSize.height / displayBounds.height; // 调整坐标到屏幕坐标系 const adjustedRect = { x: Math.round(rect.x * sourceScaleX), y: Math.round(rect.y * sourceScaleY), width: Math.round(rect.width * sourceScaleX), height: Math.round(rect.height * sourceScaleY) }; if (image) { // 裁剪选定区域 const cropped = image.crop(adjustedRect); // 关闭截图窗口 if (screenshotWindow) { screenshotWindow.close(); } mainWindow.webContents.send('screenshot-result', cropped.toDataURL()); return { success: true, image: cropped.toDataURL(), bounds: adjustedRect }; } return { success: false, error: '无法获取屏幕截图' }; } catch (error) { console.error('截图失败:', error); return { success: false, error: error.message }; } }); ``` ## 工程目录 ``` ElectronCaptureDemo ├──README.md ├──libaddonNode // 调用系统截图接口的代码 └──app ├──preload // 预加载模块 │ └──preload.js // 主窗口的预加载模块 ├──renderer // 渲染进程模块 │ ├──capture.html // 主窗口加载的页面 │ ├──screenshotArkTSAPI.html // 调用系统接口截屏窗口加载的页面 │ └──screenshotElectronAPI.html // 调用electron接口截屏窗口加载的页面 ├──main.js // 主进程 ├──electron_white.png // 应用图标 └──package.json // 配置程序入口 ``` ## 参考文档 [desktopCapturer](https://www.electronjs.org/docs/latest/api/desktop-capturer) [nativeImage](https://www.electronjs.org/docs/latest/api/native-image) [screen](https://www.electronjs.org/docs/latest/api/screen)