在Android上的Chrome中获取物理屏幕尺寸/ dpi /像素密度


88

有没有安全的方法可以在Android上的Chrome中获取实际正确的屏幕物理尺寸?如有必要,可以将旧版本的Chrome和Android排除在外。

先前的研究

关于从Javascript(或CSS)中获取设备的实际物理屏幕尺寸的问题,stackoverflow上有很多死胡同的问题。似乎html api标准化与实际的浏览器实现之间没有融合,更不用说浏览器实现依赖于OS api,而OS api则依赖于提供正确信息的硬件。

顺便说一下,在假设当时盛行的某个像素密度的情况下,某些先验答案是奥术(2011年之类),因此毫无用处。其他则与webkit有关,而Chrome闪烁可能已取代了Chrome(?)中的webkit。

我想通过将事物限制为仅适用于Android上的Chrome来探索简单解决方案的存在。

注意

这全部与浏览器内部的javascript(或css)解决方案有关,而不是针对本机应用程序的解决方案。


21
那是完全错误的。我的用户界面想要了解诸如用户看到的按钮应该有多大之类的信息。您可能对代码开发者的想法太多了;)
matanster 2014年

12
例如,按钮的大小不应是视口的百分比,而应足以触摸。我不确定这对于高质量的设计有何意义。
matanster 2014年

16
@matt是绝对正确的。Web UX / UI的最重要方面之一,尤其是在胖手指的世界中,要确保按钮既适合于指针(在这种情况下为手指),也适合于可视距离的大小从屏幕到眼睛。移动设备的这一新领域使事情变得复杂,因此物理屏幕尺寸检测更为重要。
2014年

7
我与您100%@matt。我不明白为什么Mozilla和Google不能仅仅给我们一个JavaScript属性window.screenDensity,该属性包含您和我的设备(每英寸)可以从那里获取的每英寸设备的物理像素。window.screenHeight并且window.screenWidth以物理毫米为单位也很好。
trusktr 2014年

7
@Kinlan物理屏幕大小通常很重要。这就是为什么本机开发目前比Web开发更强大的原因。例如,在本机环境中,我可以在所有现代设备上制作一个1(实际)英寸宽的按钮。据我所知,这在Web环境中当前是不可能的。我错过了什么吗?
trusktr 2014年

Answers:


118

您无法真正获得实际的物理尺寸或实际的DPI,即使可以,也无法对其进行任何处理。

这是一个漫长而复杂的故事,请原谅。

网络和所有浏览器都将1px定义为一个称为CSS像素的单位。CSS像素不是真实像素,而是基于设备的可视角度被认为是英寸的1/96英寸的单位。这被指定为参考像素

参考像素是设备上一个像素的可视角度,像素密度为96dpi,并且距阅读器的距离为臂长。因此,对于28英寸的标称臂长,可视角度约为0.0213度。为了在臂长处读取,1px因此对应于约0.26毫米(1/96英寸)。

在0.26mm的空间中,我们可能会有很多实际的设备像素。

浏览器执行此操作的主要原因是传统原因-网络诞生时大多数显示器的分辨率均为96dpi-也是为了保持一致性,在过去,“ 800x600” 15英寸屏幕上的22px按钮将是“ 22px”按钮尺寸的两倍。 15英寸的显示器(分辨率为1600x1200)。在这种情况下,屏幕的DPI实际上是2倍(水平分辨率是两倍,但在相同的物理空间中)。对于网络和应用程序而言,这是一个糟糕的情况,因此大多数操作系统设计了许多方法来将像素值抽象到独立于设备的单元中(Android上为DIPS,iOS上为PT,网络上为CSS Pixel)。

iPhone Safari浏览器是第一个(据我所知)引入视口概念的浏览器。创建此文件是为了使完整的桌面样式应用程序可以在小屏幕上呈现。视口定义为960px宽。这实际上将页面缩小了3倍(iphone最初为320px),因此1个CSS像素是物理像素的1/3。当您定义视口时,虽然可以使该设备在163dpi时匹配1 CSS像素= 1实际像素。

通过使用宽度为“ device-width”的视口,您不必将每个设备的视口宽度设置为最佳CSS像素大小,浏览器便会为您完成此工作。

随着双重DPI设备的推出,手机制造商不希望手机页面缩小50%,因此他们引入了一个名为devicePixelRatio的概念(我相信首先是在移动Webkit上),这使他们可以将1个CSS像素保持为大约1 / 96英寸,但请您理​​解,诸如图像之类的资产可能需要两倍大小。如果您查看iPhone系列的所有设备,则以CSS像素表示的屏幕宽度为320px即使我们知道事实并非如此。

因此,如果在CSS空间中将按钮设置为22px,则物理屏幕上的表示形式为22 *设备像素比率。实际上,我说的并不是这样,因为设备像素比率也从来都不是精确的,电话制造商将其设置为一个不错的数字,例如2.0、3.0,而不是2.1329857289918...。

总而言之,CSS像素与设备无关,因此我们不必担心屏幕的物理尺寸和显示密度等问题。

这个故事的寓意是:不用担心了解屏幕的物理像素大小。不用了 50px在所有移动设备上看起来应该大致相同,但可能略有不同,但是CSS Pixel是我们独立于设备的方式来构建一致的文档和UI

资源:


1
@matt在平板电脑上也一样。就像视网膜Mac书籍一样。目标是在所有平台上“ CSS像素”相对统一,尤其是在您设置视口宽度=设备宽度时。
Kinlan 2014年

14
您说“您无法对他们做任何事”。我不同意。有了该信息,我将能够设置高度始终为16点(实际英寸的16 / 72nds)的字体。这是无价的,这也是本机开发继续比Web开发更强大的原因之一。
trusktr 2014年

8
实际上,以像素为单位的实际屏幕尺寸的一个完全合理的用途是渲染具有适当分辨率的背景图像。
WhyNotHugo 2015年

2
“ 50px在所有移动设备上看起来应该大致相同”,请证明彼此相邻使用例如1200x1920 4英寸手机和1000x600 10英寸平板电脑。
iloveregex

6
我也不同意“您不能对它们执行任何操作。”:您可以可靠地检测出该设备是手机还是平板电脑,并假设用户可以轻松地用手指指向屏幕上方。
Brian Cannard

11

根据Matt的回答,我进行了测试:

// on Macbook Pro Retina (2880x1800, 15.4"), is the calculated diagonal size
// approximately 15.4? Let's see...

var svgEl = document.createElementNS("http://www.w3.org/2000/svg", "svg");
var screenWidthMillimeters = svgEl.screenPixelToMillimeterX * 2880;
var screenHeightMillimeters = svgEl.screenPixelToMillimeterY * 1800;
var screenDiagonalMillimeters = Math.sqrt(Math.pow(screenWidthMillimeters, 2) + Math.pow(screenHeightMillimeters, 2)); // pythagorean theorem
var screenDiagonalInches = (screenDiagonalMillimeters / 10 / 2.54); // (mm / 10mm/cm) / 2.54cm/in = in

console.log("The calculated diagonal of the screen is "+screenDiagonalInches+" inches. \nIs that close to the actual 15.4\"?");

这是输出:

The calculated diagonal of the screen is 35.37742738560738 inches. 
Is that close to the actual value of 15.4?

不。

因此,似乎尚无办法在Web浏览器中获得真实的物理价值。


我不确定您指的是什么答案(我在任何地方都看不到“ Matt”),但是由于svgEl.screenPixelToMillimeterX显然未定义,所以我得到了NaN 。
迈克尔

6

您可以创建任何页面元素,并使用实际物理单位设置其宽度。例如

<div id="meter" style="width:10cm"></div>

然后获取其宽度(以像素为单位)。例如下面的html代码(我使用过JQuery)以厘米为单位显示设备屏幕宽度

<script>
var pixPer10CM = $('#meter').width();
var CMPerPix = 10 / pixPer10CM;
var widthCM = screen.width * CMPerPix;

alert(widthCM);
</script>

哇,我从未意识到您可以使用CSS做到这一点。这有多精确?您的浏览器如何知道屏幕的物理尺寸?caniuse.com上与此相关的浏览器兼容性吗?我找不到
杰克·威尔逊

4
W3C网站说:“过去,CSS要求即使在计算机屏幕上,实现也必须正确显示绝对单位。但是,由于错误实现的数量超过正确的实现,而且情况似乎并没有改善,因此CSS在2011年放弃了这一要求。目前,绝对单位必须只能在打印输出和高分辨率设备上正常工作。CSS并未定义“高分辨率”的含义,但由于当今低端打印机的起始分辨率为300 dpi,而高端屏幕的起始分辨率为200 dpi,截止点可能介于两者之间。”
迈克

1
我认为浏览器像其他任何本机应用程序一样,都可以通过由设备驱动程序提供给OS的OS API来获得设备解析。准确性取决于此信息。
迈克(Mike)

但是设备分辨率与实际物理尺寸不同。14英寸笔记本电脑和15英寸笔记本电脑可能具有相同的分辨率。
杰克·威尔逊

6
没有!你不能 Css中的10厘米实际大小会有所不同。如果实际上有10厘米,12厘米或7厘米,这纯粹是运气问题。这是我基于该解决方案返回错误值的jsfiddle演示,因为浏览器的行为始终像是每英寸像素(dpi):jsfiddle.net/Lzsm3zo9
Dariusz Sikorski

5

您可以通过WURFL获取该信息:

设备显示属性

这些属性称为:

resolution_(width|height)

physical_display_(width|height)

长版:

实现此目标的最佳策略是user agent string将浏览器的WURFL到可以提供所需信息的最新(或其他)DB。

用户代理字符串

这是所有现代浏览器都可以提供的信息。它公开有关设备及其操作系统的信息。没有像这样的字典的帮助,它对您的应用程序来说只是不够有意义WURFL

伍尔夫

这是通常用于检测的数据库设备属性。

有了它,您也许可以准确地支持市场上大多数流行的设备。我会发布一个代码演示,但该演示可在WURFL网站上下载。您可以在与库一起下载的examples / demo文件夹中找到这样的演示。

下载WURFL

以下是有关检查物理尺寸和分辨率的更多信息和说明:http : //www.scientiamobile.com/forum/viewtopic.php?f=16&t=286


3

作为“对这个问题没有好的解决方案”答案的补充,只需检查可在CSS https://www.w3schools.com/cssref/css_units.asp上使用的单位

Unit    Description
cm      centimeters
mm      millimeters
in      inches (1in = 96px = 2.54cm)
px *    pixels (1px = 1/96th of 1in)
pt      points (1pt = 1/72 of 1in)
pc      picas (1pc = 12 pt)

* Pixels (px) are relative to the viewing device.
For low-dpi devices, 1px is one device pixel (dot) of the display.
For printers and high resolution screens 1px implies multiple device pixels.

通过此描述,似乎有解决方案。cmmm并且in将用于绘制相同尺寸独立于屏幕大小和分辨率的东西。考虑到这一点,你可以期望的至少一个pxptpc使用,无论您想使用什么精度都可以使用来画像素级(否则,拥有数百万个像素有什么意义呢?)。好吧,不。所有单位都是公制单位的分数,因此所有这些单位只是比例不同。故事中最糟糕的是,这些都不是准确的事实。只需玩w3schools示例(画一条20厘米的线并用尺子测量)即可。

那么到底: -有没有办法来绘制精确的物理尺寸(这应该是与本案的东西cmmmin,并最终ptpc)。-无法绘制与屏幕大小和分辨率无关的相同大小的东西(至少应该是这种情况px)。

这既是实现问题(未使用实际的屏幕尺寸)又是设计问题(为什么px在已经有这么多单元的情况下,为什么应与屏幕尺寸无关)。


2

我通过我的一个Web项目http://www.vinodiscover.com解决了这个问题。答案是,您无法确定物理尺寸是多少,但可以得出一个近似值。使用JS和/或CSS,您可以使用媒体查询找到视口/屏幕的宽度和高度以及像素密度。例如:iPhone 5(326 ppi)= 320px x 568px和2.0像素密度,而Samsung Galaxy S4(441ppi)= 360px x 640px和3.0像素密度。有效的1.0像素密度约为150 ppi。

鉴于此,无论像素密度如何,我都将CSS设置为在宽度小于284px时显示1列;然后在284px和568px之间的两列;然后是852px以上的3列。这比看起来要简单得多,因为浏览器现在可以自动进行像素密度计算。

http://www.quirksmode.org/blog/archives/2010/04/a_pixel_is_not.html


3
在本机开发中,您可以获得确切的价值。本地+1,网络-1。
trusktr 2014年

您可以在Android中获得确切的实际尺寸吗?
阿波罗·克拉克


2

作为对zehelvion关于使用WURFL查找分辨率的答复的回应,还值得一提的是WURFL还可以作为JavaScript片段使用

wurfl.io提供的免费版本中,您将不会获得有关屏幕和分辨率的信息(仅设备名称,外形尺寸以及移动/非移动设备),但是这里还有一个具有更多功能的商业版本。


3
我建议将其纳入对该特定答案的评论中。
darkgaze

1
这对于应该由浏览器本地提供的东西来说是一个非常荒谬的解决方案。
迈克尔

2

CSS像素并不是我们真正的“设备独立像素”。Web平台由多种设备类型组成。虽然在手持设备上看起来CSS像素看起来非常稳定,但是在普通的96dpi台式机显示器上,它将增加50%。看我的问题。在某些情况下,这确实不是一件坏事,例如,在较大的屏幕上,字体应该更大,因为到眼睛的距离更大。但是ui元素的尺寸应该非常一致。假设您的应用有一个顶部栏,您希望它在台式机和移动设备上具有相同的厚度,默认情况下它会缩小50%,这不好,因为可触摸元素应该更大。我发现的唯一解决方法是根据设备DPI应用不同的样式。

您可以使用window.devicePixelRatio在JavaScript中获取屏幕DPI。或CSS查询:

@media  only screen and (-webkit-min-device-pixel-ratio: 1.3),
    only screen and (-o-min-device-pixel-ratio: 13/10),
    only screen and (min-resolution: 120dpi)
    {
     /* specific styles for handhelds/ high dpi monitors*/
    }

我不知道如何在高dpi台式机显示器上应用此功能。也许元素太小。Web平台没有提供更好的服务真是可惜。我想蘸的实现不会太难。


不,你不能。媒体查询正在执行这种愚蠢的“假定96dpi”废话,即它们向您说谎有关读取的DPI是什么。
迈克尔

1

我在您的评论中注意到,您实际上关心的是按钮等的大小向观众显示。

我遇到了同样的问题,直到发现这只是在HTML标头中添加一个meta标签来设置初始比例的问题:

<meta name="viewport" content="width=device-width, initial-scale=1">



0

使用getPPI()函数(移动网络:如何获取物理像素大小?),使用以下公式来获得1英寸的ID:

var ppi = getPPI();
var x   = ppi * devicePixelRatio * screen.pixelDepth / 24;
$('#Cubo').width (x);
$('#Cubo').height(x);

<div id="Cubo" style="background-color:red;"></div>

5
为什么选择pixelDepth?pixelDepth与颜色深度无关,在这种情况下,我想知道它与这里的计算
有何关系

0

希望我能回答这个问题,但是极客构建API并没有提供基本的必需品,并且有时抽象的东西太多了。

顺便说一句,我拥有40年的UI和软件设计设计经验,并且自从“ VESA”驱动程序问世以来就一直致力于实现这一目标。

对于触摸屏,我有一个叫做“ fingerSize()”的东西,它的像素数为1cm(非常接近手指的平均触摸区域的直径),但根数为“ dpcm”。

您想要显示的另一件事是“视角”。用于查看和触摸功能的显示设备的类型几乎定义了查看距离。

    (Not code but I wanted fixed width font)

    Hand held - Phone/Tablet         25cm 
    Touch screen / Desktop Monitor   40cm         ( seated or standing at a counter
                                                    with partially extended arm )
    "Personal" Touch kiosk        50cm -> 80cm ( a bit further away standing 
                                                 extended arms and standing back 
                                                 to view )
    Presentation Screen.          any distance ( angle of view derived from pixel
                                                 width of device. An ideal conventional cinema 
                                                 seat (as opposed to imax or immersive) 
                                                 you want about 50 degrees
                                                 between edges of the screen. from viewer POV )

    So what you want universally available is:

    device usage type.
    finger size in pixels (dots per CM)
    pixel dimensions of display.

    Then internally, when laying out and drawing you want the size/shape of a pixel 
    for the current transform. 

这就是我们试图在API中提供的内容,但是在许多情况下很难做到。


-1

您可以粗略估算出大小,但这并不准确。

我整理了一个示例,在几个设备上进行了测试,以查看结果。我的iPhone 6返回的值大了约33%。我的Mac上的27英寸台式机显示器报告为30英寸显示器。

var $el = document.createElement('div');
$el.style.width = '1cm';
$el.style.height = '1cm';
$el.style.backgroundColor = '#ff0000';
$el.style.position = 'fixed';
$el.style.bottom = 0;
document.body.appendChild($el);
var screenDiagonal = Math.sqrt(Math.pow((window.screen.width / $el.offsetWidth), 2) + Math.pow((window.screen.height / $el.offsetHeight), 2));
var screenDiagonalInches = (screenDiagonal / 2.54);
var str = [
  '1cm (W): ' + $el.offsetWidth + 'px',
  '1cm (H): ' + $el.offsetHeight + 'px',
  'Screen width: ' + window.screen.width + 'px',
  'Screen height: ' + window.screen.height + 'px',
  'Browser width: ' + window.innerWidth + 'px',
  'Browser height: ' + window.innerHeight + 'px',
  'Screen available width: ' + window.screen.availWidth + 'px',
  'Screen available height: ' + window.screen.availHeight + 'px',
  'Screen width: ' + (window.screen.width / $el.offsetWidth).toFixed(2) + 'cm',
  'Screen height: ' + (window.screen.height / $el.offsetHeight).toFixed(2) + 'cm',
  'Screen diagonal: ' + screenDiagonal.toFixed(2) + 'cm',
  'Screen diagonal: ' + screenDiagonalInches.toFixed(2) + 'in',
  'Device Pixel Ratio: ' + (window.devicePixelRatio || 1)
].join('\n');
var $pre = document.createElement('pre');
$pre.innerHTML = str;
document.body.appendChild($pre);

http://codepen.io/kus/full/xOAPYB/


1
我的40英寸报告为22英寸。
RobotRock

我也不准确。我认为问题是由于window.devicePixelRatio。在Apple Thunderbolt屏幕上为1,在Macbook Pro Touchbar 15“上为2。此值是否始终是整数?因为这是一个比率,所以这没有意义。其他元素:stackoverflow.com/questions/16385573/…
汤姆(Tom),
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.