iT邦幫忙

2024 iThome 鐵人賽

DAY 23
0

桌面應用中實作基礎的截圖功能是十分常見的需求,但隨著應用的複雜度增加,開發者往往需要提供更進階的截圖功能,以滿足使用者的多樣化需求。在這篇文章中,我們將探討如何在 Electron 中實作進階的截圖功能,包括 多螢幕支援、選擇性截圖、截圖後的編輯 以及 自訂快捷鍵 來觸發截圖操作。

多螢幕支援

在多顯示器環境中,使用者往往需要對不同的螢幕進行截圖,甚至同時截取多個螢幕的畫面。這是一個比較常見的需求,特別是在需要進行全屏截圖或跨螢幕操作的應用中。

獲取多螢幕資訊

為了支援多螢幕截圖,首先需要獲取所有顯示器的資訊。這可以通過 screen 模組來實現,該模組提供了 getAllDisplays() 方法,可以返回所有顯示器的詳細資訊。

const { screen } = require('electron');

// 獲取所有顯示器的資訊
const displays = screen.getAllDisplays();
displays.forEach((display, index) => {
  console.log(`顯示器 ${index + 1}: 寬度 = ${display.size.width}, 高度 = ${display.size.height}`);
});

針對特定螢幕進行截圖

接著,我們可以使用 screenshot-desktop 這樣的第三方模組,來實現特定顯示器的截圖功能。這個模組允許我們指定要截圖的顯示器,並且能夠獲取多螢幕中的特定畫面。

const screenshot = require('screenshot-desktop');

// 截取特定顯示器的截圖
function captureDisplay(displayId) {
  screenshot({ screen: displayId }).then((img) => {
    // 將截圖保存為文件
    fs.writeFileSync(`screenshot-display-${displayId}.png`, img);
    console.log(`顯示器 ${displayId} 的截圖已保存`);
  }).catch((err) => {
    console.error('截圖失敗:', err);
  });
}

選擇性截圖

除了全螢幕截圖,選擇性截圖(即使用者能拖拉選擇特定區域進行截圖)也是一個非常實用的功能,特別是當使用者只想要截取某個視窗或介面的一部分。

使用 Node.js 和原生模組

在 Electron 中,實現選擇性截圖功能通常需要結合系統的圖形界面來處理區域選擇。可以使用第三方工具如 robotjs 來監聽滑鼠事件並截取選擇的區域。

安裝 robotjs:

npm install robotjs
const robot = require('robotjs');
const screenshot = require('screenshot-desktop');

// 偵測滑鼠位置,並選擇截取範圍
function captureSelection() {
  console.log('請選擇截圖區域');
  
  // 等待使用者按下滑鼠,並開始選擇區域
  const startPos = robot.getMousePos();
  console.log(`起始位置: x = ${startPos.x}, y = ${startPos.y}`);

  // 模擬等待使用者拖拉選擇結束
  setTimeout(() => {
    const endPos = robot.getMousePos();
    console.log(`結束位置: x = ${endPos.x}, y = ${endPos.y}`);

    // 計算選擇區域的寬高
    const width = endPos.x - startPos.x;
    const height = endPos.y - startPos.y;

    // 截取該區域的螢幕內容
    screenshot({ screen: 'all', crop: { x: startPos.x, y: startPos.y, width, height } })
      .then((img) => {
        fs.writeFileSync('selected-area-screenshot.png', img);
        console.log('選擇區域的截圖已保存');
      })
      .catch((err) => {
        console.error('截取選擇區域失敗:', err);
      });
  }, 3000); // 模擬用戶拖拉時間
}

使用 HTML5 進行區域選擇

另一種方式是使用 HTML5 Canvas 在渲染程序中顯示一個透明的覆蓋層,讓使用者通過拖拽的方式選擇截圖區域,然後將該選擇區域傳回給主程序進行截圖操作。

截圖後的編輯功能

截圖完成後,提供編輯功能可以讓使用者進行標註、裁剪或添加註解等操作,這在報告問題或製作教程時特別有用。

使用第三方圖像編輯工具

你可以使用現有的 Node.js 圖像處理模組如 Jimp 來進行簡單的圖像處理,如裁剪、加框、添加文字等。

安裝 Jimp:

npm install jimp
const Jimp = require('jimp');

// 打開截圖並進行編輯
Jimp.read('selected-area-screenshot.png').then((image) => {
  // 添加文字註解
  Jimp.loadFont(Jimp.FONT_SANS_32_BLACK).then((font) => {
    image.print(font, 10, 10, '我的註解');
    
    // 保存編輯後的圖片
    image.write('edited-screenshot.png', () => {
      console.log('截圖已編輯並保存');
    });
  });
}).catch((err) => {
  console.error('圖像處理失敗:', err);
});

這樣,你可以讓使用者在截圖後對圖像進行編輯和標註,提升整體使用者體驗。

使用快捷鍵觸發進階截圖功能

為了提升使用者的操作效率,可以設置快捷鍵來觸發截圖操作。Electron 提供了 globalShortcut API 來實現全局快捷鍵註冊。

設置全局快捷鍵

可以讓應用在啟動時註冊一個快捷鍵,當使用者按下特定按鍵組合時,自動觸發截圖功能。

const { globalShortcut } = require('electron');

app.whenReady().then(() => {
  globalShortcut.register('CommandOrControl+Shift+S', () => {
    console.log('快捷鍵已觸發截圖');
    captureSelection(); // 呼叫截圖功能
  });
});

app.on('will-quit', () => {
  // 記得在應用退出時取消快捷鍵註冊
  globalShortcut.unregisterAll();
});

儲存與分享截圖

進階的截圖功能通常還需要提供截圖的儲存和分享功能。儲存截圖可以通過 fs 寫入到本地文件系統,而分享功能則可以通過郵件或直接將截圖上傳到雲端存儲服務進行實現。

儲存截圖到本地

const fs = require('fs');
const path = require('path');

function saveScreenshot(imgBuffer, fileName) {
  const filePath = path.join(__dirname, fileName);
  fs.writeFileSync(filePath, imgBuffer);
  console.log(`截圖已保存到: ${filePath}`);
}

上傳截圖到雲端

你可以結合 AWS S3、Google Cloud Storage 或 Dropbox API 來將截圖上傳到雲端,從而允許使用者分享圖片的鏈接。

const AWS = require('aws-sdk');
const s3 = new AWS.S3();

function uploadToS3(imgBuffer, fileName) {
  const params = {
    Bucket: 'your-s3-bucket-name',
    Key: fileName,
    Body: imgBuffer,
    ContentType: 'image/png'
  };

  s3.upload(params, (err, data) => {
    if (err) {
      console.error('上傳失敗:', err);
    } else {
      console.log('截圖已上傳:', data.Location);
    }
  });
}

總結

在 Electron 中實作進階截圖功能不僅僅是截取螢幕這麼簡單,還包括了如何處理多螢幕、選擇區域截圖、提供編輯工具以及快捷鍵觸發截圖等多樣化需求。透過結合內建的 API 和第三方模組,可以提供更加靈活、功能豐富的截圖功能,使應用更加實用和具備競爭力。


上一篇
實作截圖功能:初探
下一篇
實作截圖功能:螢幕錄製
系列文
從 0 到 1:30 篇文章帶你玩轉 Electron 與 React25
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言