本文概述
- 全屏截图
- 创建你的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应用的屏幕截图 要仅创建你的应用的屏幕截图, 我们将使用相同的方法, 但要进行一些修改:
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应用程序)。你可以使用每个对象(名称)的标识符来选择将使用哪个进程来创建屏幕截图。
在这种情况下, 由于我们要创建应用程序的屏幕截图, 因此需要使用摘要中的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中执行前一个代码片段时, 应产生类似于以下内容的内容:
文章图片
注意:如果你遇到黑屏(我们也遇到了这种情况, 因为你可以看到该应用程序具有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>
结果应该类似于:
文章图片
请注意, 该模块是用纯Javascript编写的, 不需要任何本机依赖, 因此它运行起来很慢。由你决定实施任何本机模块, 以便根据需要裁剪图像。
已知的问题 在某些设备中, 你可能会遇到黑屏问题, 此问题在Github中报告:
文章图片
唯一有效的解决方案是使用一些额外的参数启动应用程序, 以使用标志– 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框架中创建你的应用或屏幕的屏幕截图】玩得开心 !
推荐阅读
- WWW SQL Designer(在线SQL图表工具)
- Reko(通用二进制反编译器)
- 在Electron Framework中使用本机桌面通知
- 如何使用Electron Framework从Web视图发送检索信息和操作DOM
- 如何使用Electron Framework执行exe文件(系统应用程序)
- 使用Electron Framework监视文件和目录
- 如何使用CLI构建(发布)Electron应用程序的发行版(发布)
- 使用MediaSync的Android应用在播放视频时冻结
- Webview中的Android youtube网站正在干扰