前言

为了进一步提高开发工作效率,最近我们基于 electron 开发了一款媲美 uTools 的开源工具箱 rubick。该工具箱不仅仅开源,最重要的是可以使用 uTools 生态内所有开源插件!这将是巨大的能力,意味着 uTools 生态内所有插件可以无差异化使用到 rubick 中。

设计交互上为了更能提高用户的使用效率,我们又尝试去实现了 uTools 中非常优秀的一些设计,比如:全局取色和截屏。全局取色在获取一些图片、其他App应用的颜色时非常有用。截屏虽然可以使用钉钉或者微信自带的截图功能,但是为了更加符合 uTools 用户习惯,我们也顺便实现了一下。

接下来进入主题,我们来基于 rubick 来一步步实现一个取色和截屏能力。

代码仓库

Rubick github

功能演示:

实现取色

要实现屏幕取色能力,主要核心能力步骤如下:

  1. 跟随鼠标移动,获取当前屏幕鼠标位置
  2. 获取当前坐标的颜色

1. 获取鼠标移动的坐标

要获取系统鼠标移动的坐标,electron 本身没有提供相关的函数和能力,所以要实现跟随获取系统鼠标位置,可能要调用原生能力。好在有一个 iohook 这样一个强大的系统调用工具,可以帮助我们监听系统鼠标操作以及按键操作。所以我们可以基于 iohook 来实现位置坐标获取。在 electron 中按照 iohook,在 npm install iohook 之前,需要在 package.json 中配置:

"iohook": {
"targets": [
"node-72",
"electron-85"
],
"platforms": [
"win32",
"darwin",
"linux"
],
"arches": [
"x64",
"ia32"
]
}

后面在 install 的时候会为我们按照所需下载通过 node-gyp 编译好的 node 可调用的包。如果需要重新编译,需要再重新执行命令:

"rebuild": "npm rebuild --runtime=electron --target=5.0.0 --disturl=https://atom.io/download/atom-shell --abi=80"

具体需要哪个版本的 nodeelectron 可以参考这篇文章

准备工作做完之后,接下来就是调用 iohook 获取鼠标移动位置:

 ioHook.on('mousemove', ({x, y}) => {
// todo
})

2. 获取当前坐标位置颜色

这里,需要利用到另一个库 robotjs,该库提供了强大的系统操作能力,最最最重要的是他可以获取到像素点的色彩,这就很关键了。这个正好是我们需要的:

 let color = "#" + robot.getPixelColor(parseInt(x), parseInt(y));

到这里就基本上完成了。

另一种实现方案

上面是一种比较常规的做法,但除了上面的方式,还有没有其他的方式呢?当时我也想了很久,后来仔细想想,electron 虽然获取不到系统鼠标位置和点击以及系统级别的像素,但是如果我们的屏幕本身就是一个 electronbrowserWindow 那就可以通过 DOM 来实现啦!

确实这是一个思路,核心步骤拆解下来就是:

  1. 根据当前显示器个数渲染对应个数 browserWindow
  2. 每个 browserWindow 尺寸设置成透明全屏的
  3. 获取每个 screen 的全屏截图
  4. 绘制截图到 browserWindow 的 canvas 上
  5. 从系统级操作转成 electron 内部操作

具体的实现方式这里就不细说,因为下面截屏采用的就是这种方案。

实现系统截屏

系统截屏就可以参考上面所述,采用分屏渲染子窗口,再操作子窗口的方式来实现,这里我也是参考了:从零开始用 electron 手撸一个截屏工具

最后

本篇主要介绍如何实现一个类似于 utools 的取色、截屏能力,当然这远远不是 utools 的全部,下期我们再继续介绍如何实现 utools 其他能力。欢迎大家前往体验 Rubick 有问题可以随时提 issue 我们会及时反馈。

另外,如果觉得设计实现思路对你有用,也欢迎给个 Star:https://github.com/clouDr-f2e/rubick

徒手从零实现 uTools 系列(三)- 屏幕取色和截屏的更多相关文章

  1. JavaScript零基础学习系列三

    函数 函数:为了完成某个功能而定义的代码的集体.函数是数据类型,只读的对象:函数也是对象:代码的重用.(JavaScript中) 定义语法:function 函数名(形式参数1,形式参数2--){ / ...

  2. 纯C#实现屏幕指定区域截屏

    以前在别的地方见过一个通过调用系统API实现屏幕截图的例子,从内心来说我不太喜欢在C#代码中出现这种情况,现在什么都讲“和谐”,我觉得这种做法就是破坏了我们的“和谐”代码,呵呵,开玩笑,有的时候,不通 ...

  3. C#实现屏幕指定区域截屏

    //string Opath = @"C:/Picture";            //if (Opath.Substring(Opath.Length - 1, 1) != @ ...

  4. iOS中的截屏(屏幕截屏及scrollView或tableView的全部截屏)

    iOS中的截屏(屏幕截屏及scrollView或tableView的全部截屏) 2017.03.16 12:18* 字数 52 阅读 563评论 4喜欢 2 1. 截取屏幕尺寸大小的图片并保存至相册 ...

  5. IM开发者的零基础通信技术入门(三):国人通信方式的百年变迁

    [来源申明]本文原文来自:微信公众号“鲜枣课堂”,官方网站:xzclass.com,原题为:<中国通信的百年沉浮>,本文引用时已征得原作者同意.为了更好的内容呈现,即时通讯网在收录时内容有 ...

  6. 【JAVA零基础入门系列】Day8 Java的控制流程

    什么是控制流程?简单来说就是控制程序运行逻辑的,因为程序一般而言不会直接一步运行到底,而是需要加上一些判断,一些循环等等.举个栗子,就好比你准备出门买个苹果,把这个过程当成程序的话,可能需要先判断一下 ...

  7. 【JAVA零基础入门系列】Day10 Java中的数组

    什么是数组?顾名思义,就是数据的组合,把一些相同类型的数放到一组里去. 那为什么要用数组呢?比如需要统计全班同学的成绩的时候,如果给班上50个同学的成绩信息都命名一个变量进行存储,显然不方便,而且在做 ...

  8. 【JAVA零基础入门系列】Day11 Java中的类和对象

    今天要说的是Java中两个非常重要的概念--类和对象. 什么是类,什么又是对象呢?类是对特定集合的概括描述,比如,人,这个类,外观特征上,有名字,有年龄,能说话,能吃饭等等,这是我们作为人类的相同特征 ...

  9. 【JAVA零基础入门系列】Day13 Java类的继承与多态

    继承是类的一个很重要的特性,什么?你连继承都不知道?你是想气死爸爸好继承爸爸的遗产吗?(滑稽) 开个玩笑,这里的继承跟我们现实生活的中继承还是有很大区别的,一个类可以继承另一个类,继承的内容包括属性跟 ...

随机推荐

  1. mate桌面用户 root 自动登录lightdm.conf -20190520 方法【fedora 21】mate

    桌面用户自动登录lightdm.conf -20190520 方法修改 /etc/lightdm/lightdm.conf 步骤:1 vim  /etc/lightdm/lightdm.conf 解除 ...

  2. $(cd "$(dirname "$0")",pwd) 解析

    xx.sh 文件内容如下: #!/bin/bash BIN_FOLDER=$(cd "$(dirname "$0")";pwd) echo $BIN_FOLDE ...

  3. AD中如何解决 同一局域网下证书冲突问题

    AD中如何解决  同一局域网下证书冲突问题 https://wenku.baidu.com/view/c20e1720482fb4daa58d4b52.html

  4. Flink-cdc实时读postgresql

    由于公司业务需要,需要实时同步pgsql数据,我们选择使用flink-cdc方式进行 架构图: 前提步骤: 1,更改配置文件postgresql.conf # 更改wal日志方式为logicalwal ...

  5. 西门子S7200/300/400以太网通讯处理器选型分类

    北京华科远创科技有限研发的远创智控转以太网模块适用于西门子S7-200/S7-300/S7-400.SMART S7-200.西门子数控840D.840DSL.合信.亿维PLC的PPI/MPI/PRO ...

  6. 性能调优必备:NIO的优化实现原理

    前言 我们就从底层的网络 I/O 模型优化出发,再到内存拷贝优化和线程模型优化,深入分析下 Tomcat.Netty 等通信框架是如何通过优化 I/O 来提高系统性能的. 网络 I/O 模型优化 网络 ...

  7. Guava Cache,Java本地内存缓存使用实践

    Guava Cache,网上介绍很多,我就不赘述了. 分享一篇好的文章: Guava Cache内存缓存使用实践-定时异步刷新及简单抽象封装 Google Guava 3-缓存 在原作者基础上,我做了 ...

  8. Go语言的GOPATH详解

    在GOLAND中设置GOPATH: 设置好路径后,并不是直接在这个路径下面写代码文件就行了 GO会识别GOPATH下的src目录,而真正的引用的包名,是src下的目录名,然后才是代码模块名 目录结构如 ...

  9. CUDA 9中张量核(Tensor Cores)编程

    CUDA 9中张量核(Tensor Cores)编程 Programming Tensor Cores in CUDA 9 一.概述 新的Volta GPU架构的一个重要特点是它的Tensor核,使T ...

  10. 痞子衡嵌入式:嵌入式里通用微秒(microseconds)计时函数框架设计与实现

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是嵌入式里通用微秒(microseconds)计时函数框架设计与实现. 在嵌入式软件开发里,计时可以说是非常基础的功能模块了,其应用也非常 ...