繁体   English   中英

JavaScript/NodeJS 和 Electron 中的图像 DPI?

[英]Image DPI in JavaScript/NodeJS and Electron?

我正在使用Electron构建一个主要用于 Mac OS X 的应用程序。用户可以将图像拖放到页面上,页面创建一个<img>以及拖放图像的源路径,然后用户可以看到该图像。

问题

如果用户在 Retina 显示屏上截取屏幕截图,然后将图像拖放到页面上,则图像会以双倍大小显示。 我需要以某种方式知道以其自然尺寸的一半显示此图像。

可能的解决方案

我相信如果我检查它的 DPI,我应该能够可靠地判断图像是否是视网膜图像。 在 Mac 上的预览应用程序中,我可以看到图像是 144 DPI。 本质上,如果 DPI 为 144 或更高,那么它就是视网膜,对吧?

有没有什么方法可以使用 Electron 的原生图像或 NodeJS 来读取给定图像的数据?

注意: Mac OS X 以 PNG 格式截屏,因此没有 exif 数据。

编辑和更新:我相信我可以通过查看 HEX 信息来判断图像的 DPI。 即, fs.readFileSync('file.type').toString('hex') ,然后对于 PNG 文件查找70 48 59 73 ,如此所述,或者对于 JPG 文件查找FFD8FFE000104A464946000101 ,如此所述。 我现在遇到的问题是当从剪贴板粘贴图像时尝试使用 Electron 的 NativeImage。

如果我从剪贴板粘贴 PNG 并执行nativeImage.toPng().toString('hex') ,则以下是 output:

89504e470d0a1a0a0000000d49484452000001fc000001680806000000b2a54946000005c249444154789cedd5410dc03010c0b0ae448f3f8a0dc554a9b111e4976766de05005c6d9f0e0000fe67f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f80010f0014a0204ec5f3e63f20000000049454e44ae426082

在此字符串中的何处可以找到 DPI 信息?

编辑和更新 2:我想知道这是否可能是 Electron 中的错误。当我从预览中复制 144 PPI 的图像并将其粘贴到我的应用程序中时,然后将其复制出我的应用程序并将其粘贴到新的预览中window,变为72 PPI。 Electron 有没有可能被去掉这个信息?

预览 DPI

大块

由@robertklep 请求,这里是块的屏幕截图(抱歉,我在我的应用程序中覆盖了复制,所以我现在不能实际复制文本)。

初始图像最初的

复制/粘贴后复制后

您显示的 output 看起来是原始 PNG 数据(PNG 签名是0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A )。

您可以解析数据中的不同块并查找pHYs块,这是(我认为)您需要从 Mac OS X 生成的 PNG 中提取分辨率信息的块。

一个处理所有 PNG 块的简单解析器:

var image = nativeImage.toPng(); // or the result of fs.readFile*()

function* parseChunks(data) {
  var offset = 8; // skip PNG header

  while (offset < data.length) {
    var dataLength  = data.readUInt32BE(offset);
    var chunkLength = dataLength + 12;
    var typeStart   = offset + 4;
    var dataStart   = offset + 8;
    var dataEnd     = offset + 8 + dataLength;
    var crcEnd      = dataEnd + 4;

    yield {
      type : data.toString('ascii', typeStart, dataStart),
      data : data.slice(dataStart, dataEnd),
      crc  : data.slice(dataEnd, crcEnd),
    };

    offset = crcEnd;
  }
}

for (let chunk of parseChunks(image)) {
  // Extract pixel information
  if (chunk.type === 'pHYs') {
    var ppuX = chunk.data.readUInt32BE(0);
    var ppuY = chunk.data.readUInt32BE(4);
    var unit = chunk.data.readUInt8(8); // should always be `1`
    console.log('PPI', Math.round(ppuX * 0.0254));
  }
}

正如预期的那样,这会在我的 Mac 上输出PPI 144

我发现您现在可以通过clipboard.readBuffer("public.png")访问原始 PNG 剪贴板数据以获取屏幕截图。 有关其工作原理的详细信息,请参阅https://ocadaruma.hatenablog.com/entry/2023/01/29/091354

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM