screenshots icon indicating copy to clipboard operation
screenshots copied to clipboard

希望能支持多屏的跨屏截图

Open simo-an opened this issue 3 years ago • 7 comments

思路

获取所有屏幕的最大宽高,然后在讲electron窗口设置为这个宽高 获取每一个显示器的位置,截取屏幕,然后根据位置在electron窗口中画出来 然后截取这个Electron窗口的图片,以此来进行截图(或者直接拼接成一张图片亦可)

// 以下为主进程代码

import { screen, Rectangle, DesktopCapturerSource } from 'electron'

export interface Point {
  x: number, y: number
}
export interface Shape {
  width: number, height: number
}
export interface Display {
  id: string,
  rawBound: Rectangle, // 原始
  display: Rectangle, // 显示(可能右缩进)
  source?: DesktopCapturerSource
}
export interface DisplayInfo {
  leftTop: Point, // 屏幕最左上角坐标
  outline: Shape, // 屏幕最大外框宽高
  displayList: Display[] // 从左到右,从上到下的屏幕阵列
}

export const getDisplayInfo = (): DisplayInfo => {
  const displayList = screen.getAllDisplays()
  const primaryDisplay = screen.getPrimaryDisplay()

  // 安装从左到右,从上到下的顺序排序
  displayList.sort((display1, display2) => {
    const bound1 = display1.bounds
    const bound2 = display2.bounds

    if (bound1.x > bound2.x) return 1 // x 较小的排在前面
    if (bound1.x === bound2.x) {
      if (bound1.y > bound2.y) return 1 // x 相同时,y较小的排在前面
    }
    return -1 // 剩下的排在后面
  })

  let leftX = primaryDisplay.bounds.x
  let topY = primaryDisplay.bounds.y
  let rightX = primaryDisplay.bounds.x + primaryDisplay.bounds.width
  let bottomY = primaryDisplay.bounds.y + primaryDisplay.bounds.height

  displayList.forEach(display => {
    leftX = Math.min(display.bounds.x, leftX)
    topY = Math.min(display.bounds.y, topY)
    rightX = Math.max(display.bounds.x + display.bounds.width, rightX)
    bottomY = Math.max(display.bounds.y + display.bounds.height, bottomY)
  })

  const outlineWidth = rightX - leftX
  const outlineHeight = bottomY - topY

  const displayInfo = {
    leftTop: { x: leftX, y: topY },
    outline: { width: outlineWidth, height: outlineHeight },
    displayList: displayList.map(display => {
      const { id, bounds, scaleFactor } = display
      return {
        id: id.toString(),
        rawBound: bounds,
        display: {
          x: bounds.x,
          y: bounds.y,
          width: bounds.width * scaleFactor,
          height: bounds.height * scaleFactor
        }
      }
    })
  }

  return displayInfo
}

simo-an avatar May 28 '21 02:05 simo-an

理论上是可以这么干的,就是不知道会不会有性能问题,且mac系统肯定不支持跨屏幕

nashaofu avatar Jun 01 '21 12:06 nashaofu

@nashaofu Is there any chance for this solution to be merged?

bruceauyeung avatar Aug 12 '21 00:08 bruceauyeung

我这边实现了这种方案(目前只支持Win), NPM: https://www.npmjs.com/package/xw-screenshot-main 使用方法基本和当前项目相同 但是在高分屏上获取屏幕宽高和坐标有问题,后续考虑使用 C++ 拓展来获取屏幕信息

simo-an avatar Aug 12 '21 01:08 simo-an

可以提交个pr吗,加个配置是否开启跨屏,然后发一版

meteor199 avatar Sep 27 '21 09:09 meteor199

非常欢迎

发自我的华为手机

nashaofu avatar Sep 27 '21 10:09 nashaofu

我这边实现了这种方案(目前只支持Win), NPM: https://www.npmjs.com/package/xw-screenshot-main 使用方法基本和当前项目相同 但是在高分屏上获取屏幕宽高和坐标有问题,后续考虑使用 C++ 拓展来获取屏幕信息

期待 PWP2NCYHK$1{ 5B~{X3{`V2

meteor199 avatar Sep 27 '21 10:09 meteor199

后续会支持多屏截图吗

LiveDragon avatar Mar 01 '22 09:03 LiveDragon