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

Javascript 如何从JS中的图像获取DPI?,javascript,html,html5-canvas,Javascript,Html,Html5 Canvas,我在HTML5画布上计算图像上两点之间的距离。我想将这个距离(以像素为单位)转换为厘米。我找到了一个公式:像素*2.54/DPI。所以,我想知道是否有可能在JS中获得DPI图像属性?或者,我可以用最简单的方法从像素计算厘米吗 谢谢。您可以使用JavaScript从图像中获取cms的大小。注意每个设备的DPI不同,因此,我使用window.devicePixelRatio获取屏幕的DPI,显示图像可以是笔记本电脑、手机、平板电脑等 一种方法是: /* Convert px to cm */ fun

我在HTML5画布上计算图像上两点之间的距离。我想将这个距离(以像素为单位)转换为厘米。我找到了一个公式:像素*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;
另一种方法是:您将需要一个额外的库:并使用其EXIF解析扩展

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

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

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

您可以使用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;
另一种方法是:您将需要一个额外的库:并使用其EXIF解析扩展

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

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

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

您所要求的是,检索任何数字的物理显示大小(以厘米为单位),这离不开大量的启发,也就是说,作为web开发人员,我们无法为所有的访问者执行此操作

关于您的配方: 新闻部-。 这是一个衡量一英寸可以容纳多少个点的指标。该装置通常用于打印机或扫描仪。然而,监视器没有点,因此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监视器中,一个物理像素由三个二极管组成,一个红色、一个绿色和一个蓝色,也称为子像素

您可以看到构成单个像素的所有三个子像素组件。 图片来源: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...
但如果不是我的屏幕PPI,我听说的window.devicePixelRatio是什么

为了解释这一点,我们首先需要解释什么是CSS px

CSS px-读取为像素,但不是像素。 px是一个单位,CSS的神奇单位。它的价值取决于支撑,以及它与观众眼睛的距离!。您可以找到一个非常容易理解的解释,说明什么是CSS的参考像素。 基本上,它看起来应该是一样的 如果您在显示器上以有害距离观看,如果您在手机上以较近距离观看,请选择大小

我希望你明白,要将这一点映射到现实生活中的衡量标准是多么困难

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

如果我们知道CSS px真正代表的是什么,即我们是在显示器上还是在移动设备上还是在其他设备上?用户显示器的当前PPI分辨率是多少,但我们不知道,那么我们可以测量显示器上显示的大小。但我们不能

因此,是的,我们可以在96PPI桌面显示器上,在没有操作系统缩放的情况下,获得答案说明中提供的@JuMoGar类型或公式,尽管他们弄错了:

const CSSpxTocm = (CSSpx) => CSSpx * 2.54 / (96 / devicePixelRatio);
其中96是CSS px单元在其第96英寸中使用的96PPI硬编码值

但只要在手机上试一下,你就会发现它有多坏

const CSSpxTocm=CSSpx=>CSSpx*2.54/96/devicePixelRatio; console.logCSSpxTocm96+'cm'; .测试{ 边框顶部:3件纯蓝; 高度:10px; 宽度:96px; }
您所要求的是,检索任何数字的物理显示大小(以厘米为单位),这离不开大量的启发,也就是说,作为web开发人员,我们无法为所有的访问者执行此操作

关于您的配方: 新闻部-。 这是一个衡量一英寸可以容纳多少个点的指标。该装置通常用于打印机或扫描仪。然而,监视器没有点,因此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监视器中,一个物理像素由三个二极管组成,一个红色、一个绿色和一个蓝色,也称为子像素

您可以看到构成单个像素的所有三个子像素组件。 图片来源: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...
但如果不是我的屏幕PPI,我听说的window.devicePixelRatio是什么

为了解释这一点,我们首先需要解释什么是CSS px

CSS px-读取为像素,但不是像素。 px是一个单位,CSS的神奇单位。它的价值取决于支撑,以及它与观众眼睛的距离!。您可以找到一个非常容易理解的解释,说明什么是CSS的参考像素。 基本上,如果你在显示器上观看距离较近的视频,或者在手机上观看距离较近的视频,视频的大小应该相同

我希望你能 et将此映射到实际测量值有多难

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

如果我们知道CSS px真正代表的是什么,即我们是在显示器上还是在移动设备上还是在其他设备上?用户显示器的当前PPI分辨率是多少,但我们不知道,那么我们可以测量显示器上显示的大小。但我们不能

因此,是的,我们可以在96PPI桌面显示器上,在没有操作系统缩放的情况下,获得答案说明中提供的@JuMoGar类型或公式,尽管他们弄错了:

const CSSpxTocm = (CSSpx) => CSSpx * 2.54 / (96 / devicePixelRatio);
其中96是CSS px单元在其第96英寸中使用的96PPI硬编码值

但只要在手机上试一下,你就会发现它有多坏

const CSSpxTocm=CSSpx=>CSSpx*2.54/96/devicePixelRatio; console.logCSSpxTocm96+'cm'; .测试{ 边框顶部:3件纯蓝; 高度:10px; 宽度:96px; }
每英寸DPI点数是一种供打印机使用的信息。您不能将其用于数字媒体。这里没有度量距离的概念。例如,有人在手机上显示你的图像,有人在使用光束投影仪。DPI与屏幕相关,现在有了高密度的屏幕,我想这就是他们要问的问题。更准确地说,它被称为PPI或像素密度,但DPI很接近enough@DanielBeck不,这仍然无关紧要,无论密度是否高,当显示在监视器上时,EXIF元数据中的DPI信息都会被忽略。您混淆了光栅图像中的像素数,以及监视器用于显示CSS单元中一个像素点(称为DPR)的物理像素数。这些都是不相关的,你无法得到OP想要得到的物理显示尺寸。请注意,PPI的差异是存在的,因为至少已经制造了两台显示器。@Kaido他们使用了错误的术语,同意。但他们不是问EXIF数据,而是问画布上像素之间的物理距离。这可以从DPR中确定。@DanielBeck,仍然不能。正如我在第一篇评论中所说,你无法知道我的光束投影仪显示这幅图像的墙壁有多远,因此你无法知道显示的图像有多大。对于任何显示器,PPI信息都是不可用的,我认为操作系统也不知道,例如,如果你使用LED矩阵,就像建筑物上的一样,你可能有一个1PPI显示器,它可能仍然以2DPR显示,仅仅因为它足够大,每英寸可以使用4个像素的CSS px.DPI点,这是一个供打印机使用的信息。您不能将其用于数字媒体。这里没有度量距离的概念。例如,有人在手机上显示你的图像,有人在使用光束投影仪。DPI与屏幕相关,现在有了高密度的屏幕,我想这就是他们要问的问题。更准确地说,它被称为PPI或像素密度,但DPI很接近enough@DanielBeck不,这仍然无关紧要,无论密度是否高,当显示在监视器上时,EXIF元数据中的DPI信息都会被忽略。您混淆了光栅图像中的像素数,以及监视器用于显示CSS单元中一个像素点(称为DPR)的物理像素数。这些都是不相关的,你无法得到OP想要得到的物理显示尺寸。请注意,PPI的差异是存在的,因为至少已经制造了两台显示器。@Kaido他们使用了错误的术语,同意。但他们不是问EXIF数据,而是问画布上像素之间的物理距离。这可以从DPR中确定。@DanielBeck,仍然不能。正如我在第一篇评论中所说,你无法知道我的光束投影仪显示这幅图像的墙壁有多远,因此你无法知道显示的图像有多大。对于任何显示器来说,PPI信息都是不可用的,我认为操作系统也不知道,例如,如果你像建筑物上那样使用LED矩阵,你可能有一个1PPI显示器,它可能仍然以2DPR显示,仅仅是因为它足够大,一个CSS px可以使用4个像素。我不会重复这是多么不可靠,在对问题的评论中已经这样做了,但我会注意到它应该是96/DPR,而不是*。我不会重复这是多么不可靠,已经在对问题的评论中这样做了,但我会注意到它应该是96/DPR,而不是*。