在Electron框架中创建你的应用或屏幕的屏幕截图

本文概述

  • 全屏截图
  • 创建你的Electron应用的屏幕截图
  • 具有指定尺寸的屏幕截图
  • 已知的问题
尽管在你的应用中要求创建屏幕截图并不常见, 但是知道如何做不会对你造成伤害。此功能对于每个需要的应用程序都非常有用, 例如, 详细的错误报告!控制台错误消息在许多情况下可能无济于事, 但是, 映像可以节省很多时间。
在本文中, 你将学习如何使用desktopCapture内置组件轻松地从Desktop的不同区域在Electron中创建屏幕截图。
全屏截图 如果你需要截取整个屏幕的屏幕截图, 请使用desktopCapturer模块为你完成此工作。要处理全屏截图, 请使用以下功能:
const {desktopCapturer} = require('electron'); /** * Create a screenshot of the entire screen using the desktopCapturer module of Electron. * * @param callback {Function} callback receives as first parameter the base64 string of the image * @param imageFormat {String} Format of the image to generate ('image/jpeg' or 'image/png') **/function fullscreenScreenshot(callback, imageFormat) {var _this = this; this.callback = callback; imageFormat = imageFormat || 'image/jpeg'; this.handleStream = (stream) => {// Create hidden video tagvar video = document.createElement('video'); video.style.cssText = 'position:absolute; top:-10000px; left:-10000px; '; // Event connected to streamvideo.onloadedmetadata = http://www.srcmini.com/function () {// Set video ORIGINAL height (screenshot)video.style.height = this.videoHeight +'px'; // videoHeightvideo.style.width = this.videoWidth + 'px'; // videoWidthvideo.play(); // Create canvasvar canvas = document.createElement('canvas'); canvas.width = this.videoWidth; canvas.height = this.videoHeight; var ctx = canvas.getContext('2d'); // Draw video on canvasctx.drawImage(video, 0, 0, canvas.width, canvas.height); if (_this.callback) {// Save screenshot to base64_this.callback(canvas.toDataURL(imageFormat)); } else {console.log('Need callback!'); }// Remove hidden video tagvideo.remove(); try {// Destroy connect to streamstream.getTracks()[0].stop(); } catch (e) {}}video.srcObject = stream; document.body.appendChild(video); }; this.handleError = function(e) {console.log(e); }; desktopCapturer.getSources({ types: ['window', 'screen'] }).then(async sources => {console.log(sources); for (const source of sources) {// Filter: main screenif ((source.name === "Entire screen") || (source.name === "Screen 1") || (source.name === "Screen 2")) {try{const stream = await navigator.mediaDevices.getUserMedia({audio: false, video: {mandatory: {chromeMediaSource: 'desktop', chromeMediaSourceId: source.id, minWidth: 1280, maxWidth: 4000, minHeight: 720, maxHeight: 4000}}}); _this.handleStream(stream); } catch (e) {_this.handleError(e); }}}}); }

该函数将使用desktopCapture模块创建整个屏幕的屏幕截图。它期望将第一个参数作为函数(回调), 当准备好操作屏幕截图时将调用该函数。 (可选)你可以提供结果图像的格式作为内容类型(image / png或image / jpeg)的第二个参数。
用法
该函数的用法很简单, 你可以将其包含在html文档中, 然后从那里使用:
< !DOCTYPE html> < html> < head> < meta charset="utf-8"> < title> My Electron Screenshot App< /title> < /head> < body> < p> Testing screenshots in Electron :3< /p> < img id="my-preview"/> < input id="trigger" value="http://www.srcmini.com/Fullscreen screenshot" type="button"/> < script> //* Here the fullscreenScreenshot function *//document.getElementById("trigger").addEventListener("click", function(){fullscreenScreenshot(function(base64data){// Draw image in the img tagdocument.getElementById("my-preview").setAttribute("src", base64data); }, 'image/png'); }, false); < /script> < /body> < /html>

在Electron中执行前一个代码片段时, 应产生类似于以下内容的内容:
在Electron框架中创建你的应用或屏幕的屏幕截图

文章图片
太棒了, 甜美又简单吗?
创建你的Electron应用的屏幕截图 要仅创建你的应用的屏幕截图, 我们将使用相同的方法, 但要进行一些修改:
const {desktopCapturer} = require('electron'); /*** Create a screenshot of your electron app. You can modify which process to render in the conditional line #61.* In this case, filtered using the title of the document.** @param callback {Function} callback receives as first parameter the base64 string of the image* @param imageFormat {String} Format of the image to generate ('image/jpeg' or 'image/png')**/function appScreenshot(callback, imageFormat) {var _this = this; this.callback = callback; imageFormat = imageFormat || 'image/jpeg'; this.handleStream = (stream) => {// Create hidden video tagvar video = document.createElement('video'); video.style.cssText = 'position:absolute; top:-10000px; left:-10000px; '; // Event connected to streamvideo.onloadedmetadata = http://www.srcmini.com/function () {// Set video ORIGINAL height (screenshot)video.style.height = this.videoHeight +'px'; // videoHeightvideo.style.width = this.videoWidth + 'px'; // videoWidthvideo.play(); // Create canvasvar canvas = document.createElement('canvas'); canvas.width = this.videoWidth; canvas.height = this.videoHeight; var ctx = canvas.getContext('2d'); // Draw video on canvasctx.drawImage(video, 0, 0, canvas.width, canvas.height); if (_this.callback) {// Save screenshot to jpg - base64_this.callback(canvas.toDataURL(imageFormat)); } else {console.log('Need callback!'); }// Remove hidden video tagvideo.remove(); try {// Destroy connect to streamstream.getTracks()[0].stop(); } catch (e) {}}video.srcObject = stream; document.body.appendChild(video); }; this.handleError = function(e) {console.log(e); }; desktopCapturer.getSources({ types: ['window', 'screen'] }).then(async sources => {console.log(sources); for (const source of sources) {// Filter: main screenif (source.name === document.title) {try{const stream = await navigator.mediaDevices.getUserMedia({audio: false, video: {mandatory: {chromeMediaSource: 'desktop', chromeMediaSourceId: source.id, minWidth: 1280, maxWidth: 4000, minHeight: 720, maxHeight: 4000}}}); _this.handleStream(stream); } catch (e) {_this.handleError(e); }}}}); }

在这种情况下, 我们将在desktopCapturer.getSources方法中加载窗口和屏幕。这将为对象提供类似于以下内容的结构:
在Electron框架中创建你的应用或屏幕的屏幕截图

文章图片
该对象本身包含铬过程中的所有活动窗口(谷歌铬和Electron应用程序)。你可以使用每个对象(名称)的标识符来选择将使用哪个进程来创建屏幕截图。
在这种情况下, 由于我们要创建应用程序的屏幕截图, 因此需要使用摘要中的document.title属性按应用程序的标题(“ 我的Electron屏幕快照应用程序” )进行过滤, 以识别你的应用程序。
用法
以下代码段显示了如何使用appScreenshot函数轻松创建自己的应用程序的屏幕截图:
< !DOCTYPE html> < html> < head> < meta charset="utf-8"> < title> My Electron Screenshot App< /title> < /head> < body> < p> Testing screenshots in Electron :3< /p> < img id="my-preview"/> < input id="trigger" value="http://www.srcmini.com/Fullscreen screenshot" type="button"/> < script> //* Here the appScreenshot function *//document.getElementById("trigger").addEventListener("click", function(){appScreenshot(function(base64data){// Draw image in the img tagdocument.getElementById("my-preview").setAttribute("src", base64data); }, 'image/png'); }, false); < /script> < /body> < /html>

在Electron中执行前一个代码片段时, 应产生类似于以下内容的内容:
在Electron框架中创建你的应用或屏幕的屏幕截图

文章图片
注意:如果你遇到黑屏(我们也遇到了这种情况, 因为你可以看到该应用程序具有Windows 10风格, 但由于– disable-d3d11标志可防止黑屏, 因此屏幕截图具有Aero风格), 请使用此方法, 在” 已知问题” 区域中了解有关该问题以及如何解决它的更多信息。
具有指定尺寸的屏幕截图 如果你想指定应该截取屏幕截图的屏幕坐标, 那么对不起你, 我感到很抱歉, 因为这本来是不可能的。但是, 你可以使用一些技巧来实现你的目标。创建一个全屏快照并使用第三方图像处理模块对其进行裁剪!
在下面的示例中, 我们将使用全屏快照(由第一个功能提供), 并使用jimp模块根据屏幕根据屏幕位置裁剪应用程序(Electron应用程序)的区域不需要任何依赖关系, 并且可以使用纯JavaScript:
< !DOCTYPE html> < html> < head> < meta charset="UTF-8"> < title> Working with Screnshots!< /title> < /head> < body> < div> < img id="image-preview" /> < input type="button" id="create-screenshot" /> < /div> < script> /*** Create a screenshot of our app from afullscreenshot cropping it with Jimp module !*/document.getElementById("create-screenshot").addEventListener("click", function() {var Jimp = require("jimp"); fullscreenScreenshot(function(base64data){// add to buffer base64 image instead of saving locally in order to manipulate with Jimpvar encondedImageBuffer = new Buffer(base64data.replace(/^data:image\/(png|gif|jpeg); base64, /, ''), 'base64'); var height = window.innerHeight; var width = window.innerWidth; var distanceX = window.screenLeft; var distanceY = window.screenTop; var screenDimensions = screen.getPrimaryDisplay().size; var screenHeight = screenDimensions.height; var screenWidth = screenDimensions.width; Jimp.read(encondedImageBuffer, function (err, image) {if (err) throw err; // Show the original width and height of the image in the consoleconsole.log(image.bitmap.width, image.bitmap.height); // Resize the image to the size of the screenimage.resize(screenWidth, screenHeight)// Crop image according to the coordinates// add some margin pixels for this exampleimage.crop(distanceX + 10, distanceY - 10, width + 10, height + 50)// Get data in base64 and show in img tag.getBase64('image/jpeg', function(err, base64data){document.getElementById("image-preview").setAttribute("src", base64data); //console.log(data); }); }); }, "image/jpeg"); }, false); < /script> < /body> < /html>

结果应该类似于:
在Electron框架中创建你的应用或屏幕的屏幕截图

文章图片
请注意, 该模块是用纯Javascript编写的, 不需要任何本机依赖, 因此它运行起来很慢。由你决定实施任何本机模块, 以便根据需要裁剪图像。
已知的问题 在某些设备中, 你可能会遇到黑屏问题, 此问题在Github中报告:
在Electron框架中创建你的应用或屏幕的屏幕截图

文章图片
唯一有效的解决方案是使用一些额外的参数启动应用程序, 以使用标志– disable-d3d11或– disable-gpu阻止DX11的使用或GPU加速。
在以下示例中, 我们将在scripts元素的开始指令中将标记添加到项目的package.json中(请注意, 应用程序初始化时使用– disable-d3d11参数):
{"name": "electron-quick-start", "version": "1.0.0", "description": "A minimal Electron application", "main": "main.js", "scripts": {"start": "electron . --disable-d3d11"}, "repository": {"type": "git", "url": "git+https://github.com/electron/electron-quick-start.git"}, "keywords": ["Electron", "quick", "start", "tutorial"], "author": "GitHub", "license": "CC0-1.0", "bugs": {"url": "https://github.com/electron/electron-quick-start/issues"}, "homepage": "https://github.com/electron/electron-quick-start#readme", "devDependencies": {"electron-prebuilt": "^1.2.0"}, "dependencies": {"electron-dl": "^1.3.0"}}

然后像往常一样使用npm start启动应用程序, 这应该可以解决问题(在调试模式下应该模拟myapp.exe – argument指令), 请记住仅尝试使用1, 然后再尝试使用两者, 直到它起作用为止。
【在Electron框架中创建你的应用或屏幕的屏幕截图】玩得开心 !

    推荐阅读