Хотя требовать создания скриншота в вашем приложении не так уж и часто, знайте, как это сделать, это не повредит вам. Эта функция действительно полезна для каждого приложения, которое хочет, например, подробный отчет об ошибках! сообщение об ошибке консоли может не помочь во многих случаях, однако изображение может сохранить день.
В этой статье вы узнаете, как легко создать скриншот в Electron из разных областей рабочего стола, используя desktopCapture
встроенный компонент.
Полноэкранный скриншот
В случае, если вам нужно сделать снимок экрана целиком, используйте модуль desktopCapturer. Для обработки полноэкранного снимка используйте следующую функцию:
const {desktopCapturer, screen} = 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 tag
var video = document.createElement('video');
video.style.cssText = 'position:absolute;top:-10000px;left:-10000px;';
// Event connected to stream
video.onloadedmetadata = function () {
// Set video ORIGINAL height (screenshot)
video.style.height = this.videoHeight + 'px'; // videoHeight
video.style.width = this.videoWidth + 'px'; // videoWidth
// Create canvas
var canvas = document.createElement('canvas');
canvas.width = this.videoWidth;
canvas.height = this.videoHeight;
var ctx = canvas.getContext('2d');
// Draw video on canvas
ctx.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 tag
video.remove();
try {
// Destroy connect to stream
stream.getTracks()[0].stop();
} catch (e) {}
}
video.src = URL.createObjectURL(stream);
document.body.appendChild(video);
};
this.handleError = function(e) {
console.log(e);
};
// Filter only screen type
desktopCapturer.getSources({types: ['screen']}, (error, sources) => {
if (error) throw error;
// console.log(sources);
for (let i = 0; i < sources.length; ++i) {
console.log(sources);
// Filter: main screen
if (sources[i].name === "Entire screen") {
navigator.webkitGetUserMedia({
audio: false,
video: {
mandatory: {
chromeMediaSource: 'desktop',
chromeMediaSourceId: sources[i].id,
minWidth: 1280,
maxWidth: 4000,
minHeight: 720,
maxHeight: 4000
}
}
}, this.handleStream, this.handleError);
return;
}
}
});
}
Функция будет использовать desktopCapture
Модуль для создания скриншота всего экрана. В качестве первого параметра он ожидает функцию (обратный вызов), которая будет вызвана, когда снимок экрана будет готов к работе. При желании вы можете предоставить формат полученного изображения в качестве второго параметра с типом содержимого (image/png
или же image/jpeg
).
использование
Использование этой функции простое, вы можете включить ее в свой HTML-документ и использовать его оттуда:
My Electron Screenshot App
Testing screenshots in Electron :3
//* Here the fullscreenScreenshot function *//
document.getElementById("trigger").addEventListener("click", function(){
fullscreenScreenshot(function(base64data){
// Draw image in the img tag
document.getElementById("my-preview").setAttribute("src", base64data);
},'image/png');
},false);
Выполнение предыдущего фрагмента в электронном виде должно производить что-то похожее на:
Круто, мило и просто не так ли?
Создание скриншота вашего приложения Electron
Чтобы создать скриншот только вашего приложения, мы собираемся использовать тот же метод, но с несколькими изменениями:
const {desktopCapturer, screen} = 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) => {
// console.log('stream',stream);
// Create hidden video tag
var video = document.createElement('video');
video.style.cssText = 'position:absolute;top:-10000px;left:-10000px;';
// Event connected to stream
video.onloadedmetadata = function () {
// Set video ORIGINAL height (screenshot)
video.style.height = this.videoHeight + 'px'; // videoHeight
video.style.width = this.videoWidth + 'px'; // videoWidth
// Create canvas
var canvas = document.createElement('canvas');
canvas.width = this.videoWidth;
canvas.height = this.videoHeight;
var ctx = canvas.getContext('2d');
// Draw video on canvas
ctx.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 tag
video.remove();
try {
// Destroy connect to stream
stream.getTracks()[0].stop();
} catch (e) {}
}
video.src = URL.createObjectURL(stream);
document.body.appendChild(video);
};
this.handleError = function(e) {
console.log(e);
};
desktopCapturer.getSources({types: ['window', 'screen']}, (error, sources) => {
if (error) throw error;
// console.log(sources);
for (let i = 0; i < sources.length; ++i) {
console.log(sources);
// Filter: main screen
if (sources[i].name === document.title) {
navigator.webkitGetUserMedia({
audio: false,
video: {
mandatory: {
chromeMediaSource: 'desktop',
chromeMediaSourceId: sources[i].id,
minWidth: 1280,
maxWidth: 4000,
minHeight: 720,
maxHeight: 4000
}
}
}, this.handleStream, this.handleError);
return
}
}
});
}
В этом случае в desktopCapturer.getSources
Метод, который мы собираемся загрузить как окно, так и экран. Это обеспечит объект структурой, похожей на:
Объект сам по себе содержит все активные окна в процессе хромирования (приложения Google Chrome и Electron). Вы можете использовать идентификатор каждого объекта (имя), чтобы выбрать, какой процесс будет использоваться для создания снимка экрана.
В этом случае, так как мы хотим создать скриншот нашего приложения, вам нужно отфильтровать по названию приложения ("My Electron Screenshot App"
) с использованием document.title
свойство, используемое во фрагменте для идентификации вашего приложения.
использование
В следующем фрагменте показано, как легко создать скриншот собственного приложения с помощью appScreenshot
функция:
My Electron Screenshot App
Testing screenshots in Electron :3
//* Here the appScreenshot function *//
document.getElementById("trigger").addEventListener("click", function(){
appScreenshot(function(base64data){
// Draw image in the img tag
document.getElementById("my-preview").setAttribute("src", base64data);
},'image/png');
},false);
Выполнение предыдущего фрагмента в электронном виде должно производить что-то похожее на:
Замечания: если перед вами черный экран (это также происходит с нами, поскольку вы можете видеть, что приложение имеет стиль Windows 10, но на снимке экрана есть стиль Aero из-за --disable-d3d11
Отметьте флажок, чтобы предотвратить черный экран), используя этот метод, узнайте больше о проблеме и о том, как ее решить, в области Известные проблемы.
Снимок экрана с указанными размерами
Если вы хотите указать координаты экрана, где должен быть сделан снимок экрана, тогда я прошу прощения за то, что разочаровал вас, потому что это не возможно изначально. Тем не менее, вы можете использовать небольшую хитрость, чтобы достичь своей цели. Создайте полноэкранный снимок и обрежьте его, используя сторонний модуль для работы с изображениями!
В следующем примере мы собираемся сделать полноэкранный снимок (предоставленный первой функцией), и мы собираемся обрезать область нашего приложения (электронное приложение) с расположением окна в соответствии с экраном, используя модуль jimp который не требует никакой зависимости и работает с чистым JavaScript:
Working with Screnshots!
/**
* Create a screenshot of our app from a fullscreenshot 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 Jimp
var 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 console
console.log(image.bitmap.width, image.bitmap.height);
// Resize the image to the size of the screen
image.resize(screenWidth, screenHeight)
// Crop image according to the coordinates
// add some margin pixels for this example
image.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);
И результат должен быть примерно таким:
Обратите внимание, что этот модуль написан на чистом Javascript и не требует каких-либо собственных зависимостей, поэтому он работает медленно. Это зависит от вас, чтобы реализовать любой родной модуль, чтобы обрезать изображение в соответствии с вашими потребностями.
Известные вопросы
В некоторых устройствах вы можете столкнуться с проблемой черного экрана, сообщается в этом выпуске в Github:
Единственное известное и работающее решение - запустить приложение с некоторыми дополнительными аргументами, чтобы предотвратить использование DX11 или ускорение графического процессора с помощью флажков. --disable-d3d11
или же --disable-gpu
,
В следующем примере мы добавим флаг в package.json
проекта в инструкции по запуску элемента scripts (обратите внимание на --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, а затем с обоими, пока он не работает.
Повеселись !