JavaScript / NodeJS和Electron中的图像DPI?

时间:2015-07-17 04:27:49

标签: javascript node.js image electron

我使用Electron主要为Mac OS X构建应用程序。用户可以将图像放到页面上,页面会创建一个<img>,其中包含已删除图像的源路径,用户可以看到图像。

问题

如果用户在视网膜显示屏上截取屏幕截图然后将图像放到页面上,则图像显示的尺寸加倍。我需要以某种方式知道以一半的自然尺寸显示此图像。

可能的解决方案

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

使用Electron&#39; s Native Image还是NodeJS,有没有办法在给定图像的情况下读取这些数据?

注意: Mac OS X将截图设为PNG,因此没有exif数据。

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

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

89504e470d0a1a0a0000000d49484452000001fc000001680806000000b2a54946000005c249444154789cedd5410dc03010c0b0ae448f3f8a0dc554a9b111e4976766de05005c6d9f0e0000fe67f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f8001060f80010f0014a0204ec5f3e63f20000000049454e44ae426082

我会在此字符串中找到DPI信息吗?

编辑和更新2: 我想知道这是否是Electron中的错误。当我从预览中复制144 PPI的图像并将其粘贴到我的应用程序中时,将其从我的应用程序中复制并粘贴到新的预览窗口中,它将更改为72 PPI。电子是否有可能被剥夺这些信息?

Preview DPI

结块

@robertklep请求,这里是块的截图(抱歉,我在我的应用程序中覆盖了复制,因此我现在无法实际复制文本)。

初始图片 Initial

复制/粘贴后 After copy

1 个答案:

答案 0 :(得分:1)

您显示的输出看起来是原始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