簡體   English   中英

如何從 JS 中的圖像獲取 DPI?

[英]How can I get DPI from image in JS?

我在 HTML5 canvas 上工作來計算兩點之間的圖像距離。 我想將這個以像素為單位的距離轉換為厘米。 我找到了一個公式:像素 * 2.54 / DPI。 所以,我想知道是否可以在 JS 中獲取 DPI 圖像屬性? 或者,我可以使用最簡單的方法從像素計算厘米嗎?

謝謝你。

您可以使用JavaScript從圖像中獲取cms的大小。 請注意,每個設備中的DPI都不相同,因此,我使用window.devicePixelRatio來獲取顯示圖像的屏幕的DPI(可以是筆記本,移動設備,平板電腦等)。

一種方法是:

/* Convert px to cm */
function getSizeInCM(sizeInPX) {
   return sizeInPX * 2.54 / (96 * window.devicePixelRatio)
};

/* get width and height of an image in cms */
var img = document.getElementById('IMAGE_ID'),
var width = getSizeInCM(img.clientWidth),
var height = getSizeInCM(img.clientHeight);

如果只想獲取一張圖像的像素,則比較簡單:

var imageWidth = document.getElementById("IMAGE_ID").width;
var imageHeigth = document.getElementById("IMAGE_ID").height;

// or...

var imageWidth = document.getElementById("IMAGE_ID").clientWidth;
var imageHeigth = document.getElementById("IMAGE_ID").clientHeight;

執行此操作的另一種方法:您將需要一個額外的庫: Blueimp的Load Image庫並使用其EXIF parsing extension

這是返回其坐標分辨率的代碼:

loadImage.parseMetaData(FILE, function(meta) {
    if (!meta.exif) { return; }

    var resX = meta.exif.get('XResolution');
    var resY = meta.exif.get('YResolution');
});

您需要的是,要獲取以厘米為單位的任何數字形式的物理顯示大小,沒有很多啟發法就無法完成,也就是說, 作為Web開發人員我們無法為所有訪問者做到這一點。


關於您的公式:

DPI-每英寸點數

這是一英寸可以容納多少個點的度量。 本機通常用於打印機或掃描儀。 但是,監視器沒有點,因此DPI沒有意義。

諸如圖像之類的數字媒體可能會在其元數據中嵌入DPI信息,但這僅是有關掃描程序在生成文件時使用的設置的提示,或者是作者針對應打印的預期大小的提示。 僅少數專用軟件將使用此信息,而您的Web瀏覽器不屬於這些軟件。

數字像素-(光柵圖像單元)。

這是柵格圖形中可見信息的最小單位。 這些信息可能以多種方式存儲,但是除了創建新的偽造數據外,其他方法無法將其整除。 通常,這就是我們在1920x1080px中指的“ px ”。
為了更容易理解,我們以位圖為例,其中每個數字像素都由文件中自己的位集表示,為了使其更加容易,讓我們以一個8位位圖圖像(單色)為例。 ,通常是灰度)。 此處8位用於表示單個數字像素(色點)。 例如,我們可以使用以下信息制作2x2px位圖:

[2, 125, 255, 125, 255]
 |   |    |    |    - pixel (2,2) 100% intensity
 |   |    |     - pixel (2,1) 50% intensity
 |   |     - pixel (1,2) 100% intensity
 |    - pixel (1,1) 50% intensity
  - width (nb of digital pixels per line)
/* height can be determined by the `length of data array / width` */

但是請注意,所有光柵圖像都不是位圖,它們也不都具有位像素關系,但是它們都具有數字像素的概念,因為它們確實保留了最小的顏色信息塊。


澄清了這兩個概念之后,我們可以解釋您的公式的含義:

const pxTocm = (pixels, DPI) => pixels * 2.54 / DPI;

如果我們拍攝一個150 * 150px的光柵圖像,並使用具有300DPI分辨率的性能很好的噴墨打印機進行打印,則此公式將正確地為我們提供1.27cm或0.5in

但這僅在我們知道打印分辨率的情況下才有效


好吧,那我們就使用屏幕分辨率吧。

PPI-每英寸像素

這是大多數顯示器所需的。 與DPI非常相似,它測量監視器在一英寸中確實包含的物理像素數。
監視器的物理像素隨所用監視器的類型而變化,但是例如在大多數LCD監視器中,一個物理像素由三個二極管組成,一個紅色,一個綠色和一個藍色,也稱為子像素。

筆記本電腦的LCD屏幕上的子PIXEL顯示元素的照片
您可以看到組成單個像素的所有三個子像素組件。
圖片來源:Wikimedia.org的CC-BY-SA 4.0 Krapteek88

因此,我們確實可以將您的公式重寫為

const pxTocm(pixels, PPI) => pixels * 2.54 / PPI;

但這僅在圖像以100%顯示時才有效,即一個數字像素占用一個物理像素 ,這在網絡上很少見,此外, 我們需要知道此PPI值

從Web API,我們無法知道該PPI值。 我們甚至無法確定要顯示在監視器上,它很可能是光束投影儀,對於PPI的概念毫無意義。

我們所擁有的最接近的是屏幕分辨率(在Window.screen對象下,但是這只會給我們顯示器所擁有的數字像素數量;我們仍然會錯過該顯示器的實際物理尺寸。

PPI = Math.hypot(screen.width, screen.height) / physical_size_of_diagonal
// and we don't have any way to find this diagonal...

但是,如果不是屏幕的PPI,我聽說的window.devicePixelRatio是什么?

為了解釋這一點,我們首先需要解釋什么是CSS px

CSS px讀取為“像素”,但不是像素。

px是一個單位, 被W3C稱為 “ CSS的魔術單位” 它的值取決於支撐物及其與觀察者眼睛的距離(!)。 在這里,您可以找到關於CSS的參考像素的易於理解的解釋。 基本上,如果您在顯示器上以傷害距離觀看,並且在手機上以更近的距離觀看,則其尺寸應相同。

希望您能將其映射到實際測量中有多困難。

window.devicePixelRatio

此值表示將用於顯示CSS px的物理像素數。
可能很有用,因為有了這個值,我們可以精確地將一個css px映射到所使用的物理像素數。

如果我們知道CSS px真正代表什么(即(我們是在顯示器,移動設備還是其他設備上?),以及用戶顯示器的當前PPI分辨率是多少(但我們沒有),那么我們可以測量了顯示器上顯示的尺寸。 (但是我們不能)。

因此,是的,我們可以在沒有OS縮放的96PPI台式機顯示器上,獲得其答案中提供的種類或公式@JuMoGar(請注意,盡管他們弄錯了):

const CSSpxTocm = (CSSpx) => CSSpx * 2.54 / (96 / devicePixelRatio);

其中96是CSS px單位在96英寸處使用的96PPI硬編碼值。

但是只需在手機上嘗試一下,您就會發現它有多壞。 擺弄手機是否更容易。

 const CSSpxTocm = (CSSpx) => CSSpx * 2.54 / (96 / devicePixelRatio); console.log(CSSpxTocm(96) + 'cm'); 
 .test { border-top: 3px solid blue; height: 10px; width: 96px; } 
 <div class="test px"></div> 

在我的125PPI筆記本電腦的顯示器(1280x1080px中為13.3)上 ,這已經是錯誤的,指出它是2.54cm,而實際上大約是2.2cm,但是在我的Galaxy S6手機上, 它返回10.16cm,而IRL大約是1.7厘米。

為什么? 由於屏幕具有〜577 PPI,但每個CSS px僅使用一個物理像素 這意味着devicePixelRatio仍為1 ,但PPI距離預期值96太遠,此公式返回荒謬性。 (S6屏幕的對角線為5.1英寸,約12.9厘米)

Sharp JavaScript 庫可以很好地使用withMetadata函數獲取和設置圖像文件的分辨率/密度。

簡單的例子:

// get the metadata of an image 
sharp('input.jpg')
  .withMetadata()
  .toFile('output-with-metadata.jpg')
  .then(info => { ... });

// Set output metadata to 96 DPI
const data = await sharp(input)
  .withMetadata({ density: 96 })
  .toBuffer();

npm 模塊: sharp

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM