簡體   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