如何从JS中的图像获取DPI?

时间:2019-01-29 22:53:32

标签: javascript html html5-canvas

我在HTML5画布上工作,以计算图像在两点之间的距离。我想将此距离以像素为单位转换为厘米。我发现一个公式:像素* 2.54 / DPI。所以,我想知道是否有可能在JS中获得DPI图像属性?或者,我可以使用一种最简单的方法从像素计算厘米吗?

谢谢。

2 个答案:

答案 0 :(得分:2)

您可以使用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's Load Image library并使用其EXIF parsing extension

以下是返回其坐标分辨率的代码:

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

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

答案 1 :(得分:0)

你问什么,要检索的物理显示尺寸的厘米的任何东西数字化,不能没有很多启发,那就是,做的我们的网络开发有没有办法做到这一点对所有的观众。


关于您的公式:

DPI - Dots Per Inch

这是许多点如何能够适合单个英寸的量度。本机通常用于打印机或扫描仪。监视器没有点,因此 DPI 对此没有任何意义。

数字媒体如图像可以嵌入一个 DPI 在它们的元数据信息,但是这仅是在任一设置在扫描器用于生成所述文件的情况下,无论是一个提示由作者对预期大小应该提示的印刷即可。只有少数专用软件会使用此信息,而您的Web浏览器不属于这些软件。

数字像素-(光栅像元)。

这是raster graphic中可见信息的最小单位。这些信息可以存储在许多方面,而不是通过其他手段,而不是创造新的,假数据整除。通常是我们在 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 * 150像素的光栅图像,并使用一个相当不错的喷墨打印机具有300DPI的分辨率打印,该公式将正确地给我们1.27厘米,或0.5英寸

但是,如果我们知道打印分辨率这仅适用。


好吧,那么就让我们使用的屏幕分辨率。

PPI - 每英寸像素

这就是我们需要的大多数显示器。与DPI非常相似,它测量显示器在一英寸内包含的物理像素的数量。
什么物理像素为一个监控器被改变与所使用的显示器类型,但例如在大多数LCD显示器,一个物理象素由三个二极管,一个红色,一个绿色和一个蓝色,也称为子像素。

A photograph of sub-PIXEL display elements on a laptop's LCD screen
您可以看到组成单个像素的所有三个子像素组件。
<子> 图像币:CC-BY-SA 4.0 Krapteek88为wikimedia.org

因此,我们确实可以重写你的公式为

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...

但是我听说window.devicePixelRatio是不是屏幕的 PPI

是什么?

要说明这一点,我们首先需要说明什么是 CSS px

CSS px-读取为“像素”,但不是像素。

px是一个单位,called by W3C “ CSS的神奇单位” 。它的值取决于支持,以及其对观看者的眼睛距离(!)。 Here您可以找到关于CSS的参考像素的易于理解的解释。 基本上,它应该是相同的大小,如果你正在查看的危害距离在监视器上,如果你是在更近的距离看手机上。

我希望你是多么困难,这映射到现实生活中的测量。

window.devicePixelRatio

此值表示,将获得用于显示CSS px
物理像素的数量 这个可能很有用,因为有了这个值,我们可以精确地将一个css px映射到所使用的物理像素数。

如果我们知道什么是CSS px真正代表即(我们是一个监控器或移动设备或其他一些设备上的?),什么是我们的用户显示器的当前PPI的分辨率(但我们不” t),那么我们可以测量显示器上显示的尺寸。 (但是,我们不能)。

所以,是的,我们可以,一个96PPI桌上型显示器,没有OS变焦,拿到实物或公式@JuMoGar在他们的回答中提供(请注意,虽然自己听错了):

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

其中96是96PPI硬编码值CSS px单元在它们的一英寸的第96的用途。

但是只要在手机上尝试一下,就会发现它有多坏。 As a fiddle if it's easier from mobile.

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的笔记本电脑的显示器<子>(13.3in 1280x1080px),这已经是错了,应该说它是2.54厘米,而它在周围2.2厘米事实,但在我的Galaxy S6手机,{ {3}}是IRL时,大约1.7厘米。

为什么?由于屏幕的PPI约为577,但每个CSS px 仅使用一个物理像素。这意味着devicePixelRatio仍然是1,但是 PPI 距预期值96太远,此公式返回了荒谬性。 (S6屏幕的对角线为5.1英寸,约12.9厘米)