Сделал один некоторое время назадLinux-версия DingTalk, поскольку он основан на веб-версии, в нем отсутствуют многие функции настольных приложений. Поскольку большинство пользователей, которые его используют, являются пользователями Linux, в Linux нет функции скриншота, поэтому я решил сделать функцию скриншота по просьбе нескольких пользователей.
В настоящее время проект поддерживает скриншоты мониторов, и эффект идеально подходит для Windows. Есть определенные ошибки в Linux. В настоящее время он не может поддерживать функцию кросс-скриншотов (один скриншот охватывает два монитора). Эта статья также опубликована в Цзяньшу. также можно пойти в Цзяньшу, чтобы прочитать, порталу-у-у. Краткое описание.com/afraid/276ah 29, а не 28…
электронный скриншот API
предоставляется в электронном видеdesktopCapturerМодуль, этот модуль можно использовать только в процессе рендеринга.
Этот модуль предоставляет только один методdesktopCapturer.getSources(options, callback)
:
- options — это объект, содержащий два параметра
- типы: массив строк, в котором перечислены типы ресурсов рабочего стола, которые могут быть захвачены, доступные типы: экран и окно.
- thumbnailSize (необязательно): рекомендуется масштабировать размер миниатюры, по умолчанию {ширина: 150, высота: 150}.
- callback(error, sources) — это функция обратного вызова, которая передает два параметра:
- error: сообщение об ошибке при неудачном получении снимка экрана
- sources: представляет собой массив объектов Source, каждый Source представляет захваченный экран или отдельное окно и имеет следующие свойства
- id: идентификатор окна захвата или экрана, используемый в navigator.webkitGetUserMedia, в формате window:XX или screen:XX, XX — случайное число.
- имя: имя описания окна захвата или экрана, если ресурс является экраном, имя Весь экран или Экран; если ресурс является окном, имя является заголовком окна
- миниатюра: миниатюра экрана
Написание функции скриншота
- Чтобы соответствовать привычкам большинства пользователей, особенно тех, кто привык к функции скриншота QQ, используются сочетания клавиш.
ctrl+alt+a
сделать скриншот - Весь код обработки программы должен дождаться события готовности приложения перед обработкой, иначе будет сообщено об ошибке, поэтому весь код помещается в функцию обратного вызова события готовности.
- Чтобы отделить функцию скриншота и не мешать другим модулям, основной код процесса, относящийся к скриншоту, записывается в файл отдельно.shortcut-capture.js, и инкапсулируйте модуль как функцию, а также с помощью управления переменными, чтобы гарантировать, что модуль снимка экрана инициализации будет выполняться только один раз во всем процессе приложения.
-
Основной код процесса выглядит следующим образом
// 引入各个模块 const { globalShortcut, ipcMain, BrowserWindow, clipboard, nativeImage } = require('electron') // 保证函数只执行一次 let isRuned = false // 截图时会出现截图界面,如下就是保存截图窗口的数组 const $windows = [] // 判断是否为快捷键退出,其他的退出方式都不被允许 let isClose = false module.exports = mainWindow => { if (isRuned) { return } isRuned = true // 注册全局快捷键 globalShortcut.register('ctrl+alt+a', function () { mainWindow.webContents.send('shortcut-capture') }) // 抓取截图之后显示窗口 ipcMain.on('shortcut-capture', (e, sources) => { // 如果有以前的窗口就关闭以前的窗口 // 然后根据截图资源于屏幕数据生成窗口 closeWindow() sources.forEach(source => { createWindow(source) }) }) // 有一个窗口关闭就关闭所有的窗口 ipcMain.on('cancel-shortcut-capture', closeWindow) // 截图窗口确认截图时把数据传递到主进程 // 然后把数据写入到剪切板,并关闭窗口 // 没有直接在渲染进程把数据写入剪切板是因为在Linux上会报错 // 所以就把这一步改到主进程完成 ipcMain.on('set-shortcut-capture', (e, dataURL) => { clipboard.writeImage(nativeImage.createFromDataURL(dataURL)) closeWindow() }) } // 创建窗口 function createWindow (source) { // display为屏幕相关信息 // 特别再多屏幕的时候要定位各个窗口到对应的屏幕 const { display } = source const $win = new BrowserWindow({ title: '截图', width: display.size.width, height: display.size.height, x: display.bounds.x, y: display.bounds.y, frame: false, show: false, transparent: true, resizable: false, alwaysOnTop: true, fullscreen: true, skipTaskbar: true, closable: true, minimizable: false, maximizable: false }) // 全屏窗口 setFullScreen($win, display) // 只能通过cancel-shortcut-capture的方式关闭窗口 $win.on('close', e => { if (!isClose) { e.preventDefault() } }) // 页面初始化完成之后再显示窗口 // 并检测是否有版本更新 $win.once('ready-to-show', () => { $win.show() $win.focus() // 重新调整窗口位置和大小 setFullScreen($win, display) }) // 当页面加载完成时通知截图窗口开始程序的执行 $win.webContents.on('dom-ready', () => { $win.webContents.executeJavaScript(`window.source = ${JSON.stringify(source)}`) $win.webContents.send('dom-ready') $win.focus() }) // 加载地址 $win.loadURL(`file://${__dirname}/window/shortcut-capture.html`) $windows.push($win) } // 让窗口全屏 function setFullScreen ($win, display) { $win.setBounds({ width: display.size.width, height: display.size.height, x: display.bounds.x, y: display.bounds.y }) $win.setAlwaysOnTop(true) $win.setFullScreen(true) } // 关闭窗口 function closeWindow () { isClose = true while ($windows.length) { const $winItem = $windows.pop() $winItem.close() } isClose = false }
- Связь между основным процессом и процессом рендеринга осуществляется через модуль ipcMain.ipcMain получает данные процесса рендеринга, прослушивая события, передаваемые процессом рендеринга, а данные связи между двумя процессами могут быть только простыми объектами. Передача данных из основного процесса в процесс рендеринга достигается через метод send webContents.Процесс рендеринга реализуется через мониторинг событий объекта ipcRender.Этот же основной процесс может также проходить
webContents.executeJavaScript
Метод вводит js на страницу в виде строки для выполнения. - После запуска программы, когда пользователь нажимает клавишу быстрого доступа, начинается процесс рендеринга главного окна, чтобы сделать снимок экрана, а после того, как снимок экрана сделан, данные передаются основному процессу, а затем основной процесс создает новый окно и передает данные снимка экрана во вновь созданное окно. , затем подождите, пока пользователь сделает снимок экрана
// 主进程捕获到截图快捷键就让渲染进程截图 ipcRenderer.on('shortcut-capture', () => { // 获取屏幕数量 // screen为electron的模块 const displays = screen.getAllDisplays() // 每个屏幕都截图一个 // desktopCapturer.getSources可以一次获取所有桌面的截图 // 但由于thumbnailSize不一样所以就采用了每个桌面尺寸都捕获一张 const getDesktopCapturer = displays.map((display, i) => { return new Promise((resolve, reject) => { desktopCapturer.getSources({ types: ['screen'], thumbnailSize: display.size }, (error, sources) => { if (!error) { return resolve({ display, thumbnail: sources[i].thumbnail.toDataURL() }) } return reject(error) }) }) }) Promise.all(getDesktopCapturer) .then(sources => { // 把数据传递到主进程 ipcRenderer.send('shortcut-capture', sources) }) .catch(error => console.log(error)) })
- используется в этом проекте
webContents.executeJavaScript
Метод передачи данных скриншота на страницу - После того, как процесс рендеринга получает событие dom-ready основного процесса, он начинает отрисовывать интерфейс скриншота и инициализирует функцию перетаскивания страницы для создания скриншотов. когда пользователь нажимает
ESC
Закройте окно скриншота, когда нажата клавиша, чтобы выйти из скриншота - Функция обрезки изображения. Обрезка изображения достигается с помощью холста. Canvas может рисовать графику на основе изображения, а затем использовать API холста для получения нарисованного изображения в качестве полезного ресурса изображения, а затем отправлять его в основной процесс. Среди них основное использование холста
ctx.drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight)
метод- где изображение - это ресурс изображения
- sx и sy — начальные позиции исходных ресурсов изображения, которые нужно отрисовать.
- sWidth, sHeight исходный размер изображения для отрисовки ресурсов
- dx и dy — начальные позиции для рисования изображения на холсте.
- dWidth и dHeight — размер изображения, нарисованного на холсте.
- В этом проекте sx, sy, sWidth и sHeight — это размер перехватываемой области и координатное положение области относительно левого верхнего угла окна.И dx, и dy равны 0, что означает, что рисунок начинается с левый верхний угол холста, а dWidth и dHeight - размер перехватываемой области. , если dWidth, dHeight и sWidth, sHeight не равны, можно добиться масштабирования перехватываемой области, но в данном проекте 1:1
- После захвата воспроизводимого изображения нажмите кнопку «ОК» на панели инструментов «Снимок экрана», после чего информация об изображении будет считана с холста, а затем преобразована в URL-адрес данных и передана основному процессу.Основной процесс записывает данные изображения в буфер обмена. и закрывает окно.
- Из-за большого количества кода в процессе рендеринга окна скриншота он не будет здесь указан.GithubПосмотрите выше, прикрепите отношение процесса всего снимка экрана ниже
Наконец, если у вас есть время, вы также можете рассмотреть возможность извлечения функции скриншота отдельно и превращения ее в модуль, на который можно напрямую ссылаться в других электронных проектах. Пожалуйста, потерпите меня, если я пишу плохо.Адрес проекта GitHub:GitHub.com/эта молодая женщина/первая…