在 Android 上的 Chrome 中获取物理屏幕尺寸/dpi/像素密度
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/21680629/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Getting the physical screen dimensions / dpi / pixel density in Chrome on Android
提问by matanster
Question
题
Is there a safe way to get the actually correct screen physical dimensions in Chrome, on Android? If necessary, old versions of Chrome and Android can be left out of scope.
有没有一种安全的方法可以在 Android 上的 Chrome 中获得实际正确的屏幕物理尺寸?如有必要,可以将旧版本的 Chrome 和 Android 排除在范围之外。
Prior research
先前的研究
There are numerous dead-end questions on stackoverflow about getting the actual physical screen dimensions of a device from within javascript (or css). It seems there is no convergence between html api standardization and actual browser implementations in that, not to mention the browser implementation relies on OS api's which in turn rely on hardware providing the right information.
关于从 javascript(或 css)获取设备的实际物理屏幕尺寸的 stackoverflow 上有许多死胡同的问题。html api 标准化和实际浏览器实现之间似乎没有融合,更不用说浏览器实现依赖于操作系统 api,而操作系统 api 又依赖于提供正确信息的硬件。
Some prior answers by the way are arcane (year 2011 and the like) in assuming a certain pixel density that prevailed at that time, and therefore useless. Others relate to webkit whereas Chrome blink may have superseded webkit in chrome (?).
顺便说一句,在假设当时盛行的某个像素密度时,一些先前的答案是神秘的(2011 年等),因此毫无用处。其他与 webkit 有关,而 Chrome 闪烁可能已经取代了 chrome (?) 中的 webkit。
I would like to explore the existence of a simple solution by constraining things to only Chrome on Android.
我想通过将事情限制在 Android 上的 Chrome 来探索一个简单解决方案的存在。
Note
笔记
This is all about a javascript (or css) solution inside the browser, not a solution for a native app.
这完全是关于浏览器中的 javascript(或 css)解决方案,而不是本机应用程序的解决方案。
回答by Kinlan
You can't really get the real physical dimensions or the actual DPI and even if you could, you can't do anything with them.
您无法真正获得真实的物理尺寸或实际 DPI,即使可以,您也无法对它们做任何事情。
This is a pretty long and complex story, so forgive me.
这是一个相当长而复杂的故事,所以请原谅我。
The web and all browsers define 1px as a unit called a CSS pixel. A CSS pixel is not a real pixel, rather a unit that is deemed to be 1/96th of an inch based on the viewing angle of the device. This is specified as a reference pixel.
Web 和所有浏览器都将 1px 定义为一个称为 CSS 像素的单位。CSS 像素不是真正的像素,而是根据设备的视角被认为是 1/96 英寸的单位。这被指定为参考像素。
The reference pixel is the visual angle of one pixel on a device with a pixel density of 96dpi and a distance from the reader of an arm's length. For a nominal arm's length of 28 inches, the visual angle is therefore about 0.0213 degrees. For reading at arm's length, 1px thus corresponds to about 0.26 mm (1/96 inch).
参考像素是像素密度为 96dpi 且与阅读器的距离为一臂长的设备上一个像素的视角。因此,对于 28 英寸的标称臂长,视角约为 0.0213 度。对于手臂长度的阅读,1px 因此对应于大约 0.26 毫米(1/96 英寸)。
In 0.26mm of space we might have very many real device pixels.
在 0.26 毫米的空间中,我们可能拥有非常多的真实设备像素。
The browser does this mainly for legacy reasons - most monitors were 96dpi when the web was born - but also for consistency, in the "old days" a 22px button on a 15 inch screen at 800x600 would be twice the size of a 22px button on a 15 inch monitor at 1600x1200. In this case the DPI of the screen is actually 2x (twice the resolution horizontally but in the same physical space). This is a bad situation for the web and apps, so most operating systems devised many ways to abstract pixel values in to device independent units (DIPS on Android, PT on iOS and the CSS Pixel on the web).
浏览器这样做主要是出于遗留原因——大多数显示器在 Web 诞生时都是 96dpi——但也是为了一致性,在“过去”,在 800x600 的 15 英寸屏幕上的 22px 按钮将是 22px 按钮大小的两倍1600x1200 的 15 英寸显示器。在这种情况下,屏幕的 DPI 实际上是 2 倍(水平分辨率的两倍,但在相同的物理空间中)。这对网络和应用程序来说是一个糟糕的情况,因此大多数操作系统设计了许多方法来将像素值抽象为设备独立单元(Android 上的 DIPS、iOS 上的 PT 和网络上的 CSS 像素)。
The iPhone Safari browser was the first (to my knowledge) to introduce the concept of a viewport. This was created to enable full desktop style applications to render on a small screen. The viewport was defined to be 960px wide. This essentially zoomed the page out 3x (iphone was originally 320px) so 1 CSS pixel is 1/3rd of a physical pixel. When you defined a viewport though you could get this device to match 1 CSS pixel = 1 real pixel at 163dpi.
iPhone Safari 浏览器是第一个(据我所知)引入视口概念的。这是为了使完整的桌面风格应用程序能够在小屏幕上呈现。视口被定义为 960 像素宽。这实际上将页面缩小了 3 倍(iphone 最初是 320 像素),因此 1 CSS 像素是物理像素的 1/3。当你定义一个视口时,你可以让这个设备在 163dpi 下匹配 1 个 CSS 像素 = 1 个真实像素。
By using a viewport where the width is "device-width" frees you up from having to set the width of the viewport on a per device basis to the optimal CSS pixel size, the browser just does it for you.
通过使用宽度为“设备宽度”的视口,您无需在每个设备的基础上将视口的宽度设置为最佳 CSS 像素大小,浏览器只会为您完成。
With the introduction of double DPI devices, mobile phone manufacturers didn't want mobile pages to appear 50% smaller so they introduced a concept called devicePixelRatio (first on mobile webkit I believe), this lets them keep 1 CSS pixel to be roughly 1/96th of an inch but let you understand that your assets such as images might need to be twice the size. If you look at the iPhone series all of their devices say the width of the screen in CSS pixels is 320pxeven though we know this is not true.
随着双 DPI 设备的引入,手机制造商不希望移动页面看起来小 50%,因此他们引入了一个名为 devicePixelRatio 的概念(我相信首先在移动 webkit 上),这让他们保持 1 CSS 像素大约为 1/ 96 英寸,但让您了解您的资产(例如图像)可能需要两倍大小。如果你看看 iPhone 系列,他们所有的设备都说屏幕宽度(以CSS 像素为单位)是 320 像素,尽管我们知道这不是真的。
Therefore if you made a button to be 22px in CSS space, the representation on the physical screen is 22 * device pixel ratio. Actually I say this, it is not exactly this because the device pixel ratio is never exact either, phone manufacturers set it to a nice number like 2.0, 3.0 rather than 2.1329857289918....
因此,如果您在 CSS 空间中将按钮设置为 22 像素,则物理屏幕上的表示为 22 * 设备像素比。其实我这么说,不完全是因为设备像素比也从来不准确,手机制造商将其设置为一个不错的数字,例如 2.0、3.0 而不是 2.1329857289918....
In summary, CSS pixels are device independent and let us not have to worry about physical sizes of the screens and the display densities etc.
总之,CSS 像素与设备无关,让我们不必担心屏幕的物理尺寸和显示密度等。
The moral of the story is: Don't worry about understanding the physical pixel size of the screen. You don't need it. 50px should look roughly the same across all mobile devices it might vary a little, but the CSS Pixel is our device independent way to build consistent documents and UI's
这个故事的寓意是:不要担心了解屏幕的物理像素大小。你不需要它。50px 在所有移动设备上看起来应该大致相同,它可能略有不同,但 CSS Pixel 是我们构建一致文档和 UI 的独立于设备的方式
Resources:
资源:
- https://developers.google.com/web/fundamentals/layouts/rwd-fundamentals/set-the-viewport
- https://developers.google.com/web/fundamentals/layouts/rwd-fundamentals/size-content-to-the-viewport
- http://viewportsizes.com/
- http://www.quirksmode.org/blog/archives/2010/04/a_pixel_is_not.html
- http://en.wikipedia.org/wiki/Device_independent_pixel
- http://www.w3.org/TR/css3-values/#absolute-lengths
- https://developer.mozilla.org/en/docs/Mozilla/Mobile/Viewport_meta_tag
- https://developers.google.com/web/fundamentals/layouts/rwd-fundamentals/set-the-viewport
- https://developers.google.com/web/fundamentals/layouts/rwd-fundamentals/size-content-to-the-viewport
- http://viewportsizes.com/
- http://www.quirksmode.org/blog/archives/2010/04/a_pixel_is_not.html
- http://en.wikipedia.org/wiki/Device_independent_pixel
- http://www.w3.org/TR/css3-values/#absolute-lengths
- https://developer.mozilla.org/en/docs/Mozilla/Mobile/Viewport_meta_tag
回答by trusktr
Based on Matt's answer, I made a test:
根据马特的回答,我做了一个测试:
// 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\"?");
This is the output:
这是输出:
The calculated diagonal of the screen is 35.37742738560738 inches.
Is that close to the actual value of 15.4?
Nope.
不。
So there seems to be no way to get real physical values in a web browser yet.
所以似乎还没有办法在网络浏览器中获得真实的物理值。
回答by Mike
You can create any page element and set its width using real physical units. For example
您可以创建任何页面元素并使用实际物理单位设置其宽度。例如
<div id="meter" style="width:10cm"></div>
And then get its width in pixels. For example html code below (i used JQuery) shows device screen width in centimeters
然后得到它的宽度(以像素为单位)。例如下面的 html 代码(我使用 JQuery)以厘米为单位显示设备屏幕宽度
<script>
var pixPer10CM = $('#meter').width();
var CMPerPix = 10 / pixPer10CM;
var widthCM = screen.width * CMPerPix;
alert(widthCM);
</script>
回答by AturSams
You can get that info with WURFL:
您可以使用 WURFL 获取该信息:
The attributes are called:
这些属性被称为:
resolution_(width|height)
physical_display_(width|height)
Long version:
长版:
The best and most reliant strategy to achieve this is to send the user agent string
from the browser to a DB like WURFL
(or another) up to date DB that can provide the needed information.
实现这一目标的最佳和最依赖策略是user agent string
将浏览器中的数据发送WURFL
到可以提供所需信息的类似(或其他)最新数据库的数据库。
This is a piece of information that all modern browsers can provide; it exposes information about the device and it's OS. It is just not meaningful enough to your application without the help of a dictionary like WURFL
.
这是所有现代浏览器都可以提供的一条信息;它公开有关设备及其操作系统的信息。如果没有像WURFL
.
This is a database commonly used to detectdevice properties.
这是一个常用于检测设备属性的数据库。
With it, you may be able to accurately support most of the popular devices on the market.
I would post a code demo but one is available with the download on the WURFL
site. You can find such a demo on the examples/demo folder that is downloaded with the library.
有了它,您或许可以准确地支持市场上大多数流行的设备。我会发布一个代码演示,但可以在WURFL
网站上下载。您可以在与库一起下载的 examples/demo 文件夹中找到这样的演示。
Here is more information and explanation about checking the physical size and resolution: http://www.scientiamobile.com/forum/viewtopic.php?f=16&t=286
以下是有关检查物理尺寸和分辨率的更多信息和说明:http: //www.scientiamobile.com/forum/viewtopic.php?f=16&t=286
回答by Tom
As a complement to the ”there's no good solution to this problem” answer, just check the units you can use on CSS https://www.w3schools.com/cssref/css_units.asp
作为“这个问题没有好的解决方案”答案的补充,只需检查您可以在 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.
With this description it seemsthere is a solution. cm
, mm
and in
would be used to draw something with the same size independently of the screen size and resolution. With this in mind, you can expect that at least one of px
, pt
or pc
can be used to draw at the pixel level, for whatever precision you would like to use (otherwise, what's the point on having millions of pixels, right?). Well, no. All of the units are fractions of a metric unit, making all of these units just different scales. And the worst in the story is the fact that none of these are accurate. Just play with the w3schools example (draw a 20cm line and measure it with a ruler).
有了这个描述,似乎有一个解决方案。cm
,mm
并将in
用于绘制与屏幕大小和分辨率无关的相同大小的内容。考虑到这一点,你可以期望的至少一个px
,pt
或pc
可用于在像素级绘制,无论出于何种精密你想使用(否则,什么是在具有千万像素,右边的点?)。嗯,不。所有单位都是公制单位的分数,使所有这些单位只是不同的比例。故事中最糟糕的是,这些都不准确。只需使用 w3schools 示例(画一条 20 厘米的线并用尺子测量它)。
So in the end:
- there is no way to draw something with physical dimensions accurately (which should be the case with cm
, mm
, in
, and eventually pt
and pc
).
- there is no way to draw something with the same size independently of the screen size and resolution (which should be the case with at least px
).
所以最后: - 没有办法准确地绘制具有物理尺寸的东西(应该是cm
, mm
, in
,最终pt
和pc
)。- 无法独立于屏幕大小和分辨率(至少应该是这种情况px
)绘制相同大小的内容。
This is both an implementation problem (actual screen size not being used) and design problem (why should px
be independent of the screen size while there is already so many units for that).
这既是一个实现问题(没有使用实际的屏幕尺寸),也是一个设计问题(为什么应该px
独立于屏幕尺寸,而已经有这么多单元)。
回答by Apollo Clark
I tackled this problem with one of my web projects http://www.vinodiscover.comThe answer is that you can't know for certain what the physical size is, but you can get an approximation. Using JS and / or CSS, you can find the width and height of the viewport / screen, and the pixel density using media queries. For example: iPhone 5 (326 ppi) = 320px by 568px and a 2.0 pixel density, while a Samsung Galaxy S4 (441ppi) = 360px x 640px and a 3.0 pixel density. Effectively a 1.0 pixel density is around 150 ppi.
我用我的一个网络项目解决了这个问题http://www.vinodiscover.com答案是你不能确定物理尺寸是多少,但你可以得到一个近似值。使用 JS 和/或 CSS,您可以找到视口/屏幕的宽度和高度,以及使用媒体查询的像素密度。例如:iPhone 5 (326 ppi) = 320px x 568px 和 2.0 像素密度,而三星 Galaxy S4 (441ppi) = 360px x 640px 和 3.0 像素密度。实际上,1.0 像素密度约为 150 ppi。
Given this, I set my CSS to show 1 column when the width is less than 284px, regardless of pixel density; then two columns between 284px and 568px; then 3 columns above 852px. It's much more simple then it seems, since the browsers now do the pixel density calculations automatically.
鉴于此,我将 CSS 设置为在宽度小于 284px 时显示 1 列,而不管像素密度如何;然后是 284px 和 568px 之间的两列;然后是 852px 以上的 3 列。它比看起来要简单得多,因为浏览器现在会自动进行像素密度计算。
http://www.quirksmode.org/blog/archives/2010/04/a_pixel_is_not.html
http://www.quirksmode.org/blog/archives/2010/04/a_pixel_is_not.html
回答by jonarnes
As a response to zehelvion reply about using WURFL to find the resolution, it is also worth mentioning that WURFL is also available as a JavaScript snippet.
作为对有关使用 WURFL 查找分辨率的 zehelvion 回复的回应,还值得一提的是,WURFL 也可作为JavaScript 代码段使用。
In the free edition offered at wurfl.io, you won't get information about the screen and resolution though (only device name, form factor and mobile/not mobile), but there is also a commercial version with more capabilities available here.
在wurfl.io提供的免费版本中,您不会获得有关屏幕和分辨率的信息(只有设备名称、外形和移动设备/非移动设备),但这里还有一个具有更多功能的商业版本。
回答by Maciej Krawczyk
CSS pixels aren't really our "device independent pixel". Web platform consists of variety of device types. While CSS pixel seem to look pretty consistent on handhelds, it will be 50% bigger on a typical 96dpi desktop monitor. See my question. This is really not a bad thing in some cases, e.g. fonts should be larger on a larger screen, since distance to the eye is bigger. But ui element dimensions should be pretty consistent. Let's say your app has a top bar, you would rather want it to be the same thickness on desktop and mobiles, by default it will be 50% smaller, which is not good, because touchable elements should be bigger. The only workaround I have found is to apply different styles based on device DPI.
CSS 像素并不是真正的“设备独立像素”。Web 平台由多种设备类型组成。虽然 CSS 像素在手持设备上看起来非常一致,但在典型的 96dpi 桌面显示器上它会大 50%。看到我的问题。在某些情况下这确实不是一件坏事,例如在更大的屏幕上字体应该更大,因为到眼睛的距离更大。但是 ui 元素尺寸应该非常一致。假设您的应用程序有一个顶部栏,您希望它在桌面和移动设备上的厚度相同,默认情况下它会小 50%,这并不好,因为可触摸元素应该更大。我发现的唯一解决方法是根据设备 DPI 应用不同的样式。
You can get screen DPI in JavaScript with window.devicePixelRatio . Or CSS query:
您可以使用 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*/
}
I don't know how applying this would work on a high dpi desktop monitor though. Perhaps elements would be too small. It is really a shame that the web platform doesn't offer anything better. I guess that implementation of dip wouldn't be too hard.
我不知道如何在高 dpi 桌面显示器上应用它。也许元素太小了。网络平台没有提供更好的东西真的很遗憾。我想dip的实现不会太难。
回答by Dan Kennedy
I noticed in your comments that you were actually concerned with the size that buttons and so on appear to the viewer.
我在您的评论中注意到您实际上关心按钮等显示给观众的大小。
I was having the same problem, until I discovered that it just was a matter of adding a meta tag to the HTML header to set the initial scale:
我遇到了同样的问题,直到我发现这只是向 HTML 标头添加元标记以设置初始比例的问题:
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="viewport" content="width=device-width, initial-scale=1">
回答by peterk
Heh wish I could answer this but geeks building APIs don't provide the basic necessities and abstract things a bit too much at times.
呵呵,希望我能回答这个问题,但构建 API 的极客们并没有提供基本的必需品,有时也有些抽象的东西。
BTW I have 40 years of UI and software design design experience and have been pushing to have just this for what seems like forever since before the days of "VESA" drivers :).
顺便说一句,我有 40 年的 UI 和软件设计经验,并且在“VESA”驱动程序出现之前就一直在努力实现这一目标:)。
For touch screen I had a thing I called "fingerSize()" which was the number of pixels to be 1cm ( very close to diameter of average touch area of finger) but the root datmum is "dpcm".
对于触摸屏,我有一个我称之为“fingerSize()”的东西,它的像素数为 1cm(非常接近手指平均触摸区域的直径),但根数据是“dpcm”。
The other thing you want for a display is "angle of view" The type of display device for viewing and touch function pretty much defines viewing distance.
您需要显示器的另一件事是“视角” 用于观看和触摸功能的显示设备类型几乎定义了观看距离。
(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.
This is what we try to provide in our APIs But alas hard to get in many cases.
这就是我们试图在我们的 API 中提供的内容,但是在许多情况下很难获得。