为什么 Electron.js Clipboard 在执行 Clipboard.readImage() 时返回相同的图像两次?

问题描述 投票:0回答:1

我正在开发一个 Electron 应用程序,其中我正在实现一项功能来监视剪贴板的更改并在复制图像时捕获图像。我已经设置了一个监听器函数来使用电子模块的剪贴板功能来检测剪贴板中的图像变化。

但是,我遇到了有时会捕获重复图像的问题,特别是在 Windows 中使用截图工具时。尽管实现了过滤掉重复图像的逻辑,该应用程序仍然偶尔会捕获两张图像而不是一张。

这是我的 ClipboardWatcher 函数的简化版本:

const { clipboard } = require("electron");

export function clipboardWatcher({
  watchDelay = 1000,
  onImageChange,
  onTextChange,
}) {
  let lastText = clipboard.readText();
  let lastImage = clipboard.readImage();

  const intervalId = setInterval(() => {
    const text = clipboard.readText();
    const image = clipboard.readImage();

    if (onImageChange && imageHasDiff(image, lastImage)) {
      lastImage = image;
      onImageChange(image);
    }

    if (onTextChange && textHasDiff(text, lastText)) {
      lastText = text;
      onTextChange(text);
    }
  }, watchDelay);

  return {
    stop: () => clearInterval(intervalId),
  };
}

function imageHasDiff(a, b) {
  return !a.isEmpty() && b.toDataURL() !== a.toDataURL();
}

function textHasDiff(a, b) {
  return a && b !== a;
}

我怀疑我的 imageHasDiff 函数可能无法准确识别重复图像。是否有更好的方法来比较 Electron 应用程序中的图像以确保仅捕获唯一的图像?我是否应该考虑使用不同的方法来比较图像,例如比较像素数据或使用图像处理技术?

我注意到,当注销复制图像的数据 URL 时,我会得到同一个复制图像的两个不同的 URL。这一观察结果与我遇到的问题相符,尽管只有一张复制的图像,但仍捕获重复的图像。

任何建议或见解将不胜感激。谢谢!

javascript electron clipboard
1个回答
0
投票

我想我可能知道是什么导致了 Electron 的剪贴板两次返回相同图像的问题。这可能与复制图像时剪贴板如何处理图像数据有关。

基本上,当图像被复制到剪贴板时,它可以以多种格式存储(PNG、JPEG、TIFF 等)。这取决于进行复制的应用程序。

因此,从您的示例来看,当您使用 Clipboard.readImage() 时,Electron 从剪贴板中获取图像数据并且每次都会创建一个新的 NativeImage 对象。尽管实际图像数据保持不变,但 NativeImage 对象是单独的实例。这就是为什么当你调用 toDataURL() 时会得到不同的数据 URL。

要解决此问题并确保正确比较图像,您可以使用

toDataURL()
方法与特定图像格式并比较生成的数据 URL。

试一试:

imageHasDiff(a, b) {
  return !a.isEmpty() && b.toDataURL('image/png') !== a.toDataURL('image/png');
}

通过在 toDataURL() 方法中将图像格式指定为“image/png”,可以确保图像数据在比较之前始终转换为相同的格式。这应该可以解决重复图像的问题

另一种选择是使用 toBitmap() 方法直接比较图像数据,该方法为您提供图像的原始位图数据,但我对 toBitmap() 不太熟悉

imageHasDiff(a, b) {
  return !a.isEmpty() && !a.toBitmap().equals(b.toBitmap());
}

toBitmap() 方法返回一个 Buffer 对象,其中包含图像的原始位图数据。通过直接使用 equals() 方法比较位图数据,您可以确定图像是否相同。如果这有帮助,请告诉我,这是我第一次能够回答问题(:

© www.soinside.com 2019 - 2024. All rights reserved.