Android의 Chrome에서 실제 화면 크기 / dpi / 픽셀 밀도 가져 오기
질문
Android의 Chrome에서 실제로 올바른 화면 물리적 크기를 얻는 안전한 방법이 있습니까? 필요한 경우 이전 버전의 Chrome 및 Android는 지원 범위에서 제외 될 수 있습니다.
사전 연구
자바 스크립트 (또는 CSS) 내에서 기기의 실제 물리적 화면 크기를 가져 오는 것에 대한 stackoverflow에 대한 수많은 막 다른 질문이 있습니다. 브라우저 구현이 올바른 정보를 제공하는 하드웨어에 의존하는 OS API에 의존하는 것은 말할 것도없고 html API 표준화와 실제 브라우저 구현 사이에 수렴이없는 것 같습니다.
그런데 이전 답변 중 일부는 그 당시에 우세한 특정 픽셀 밀도를 가정하여 무의미하고 (2011 년 등) 쓸모가 없습니다. 다른 것들은 웹킷과 관련이 있지만 Chrome 깜박임은 크롬 (?)의 웹킷을 대체했을 수 있습니다.
Android의 Chrome으로 만 제한하여 간단한 솔루션의 존재를 탐색하고 싶습니다.
노트
이것은 네이티브 앱을위한 솔루션이 아니라 브라우저 내부의 자바 스크립트 (또는 CSS) 솔루션에 관한 것입니다.
실제로 실제 물리적 치수 나 실제 DPI를 얻을 수 없으며 가능하더라도 아무것도 할 수 없습니다.
이건 꽤 길고 복잡한 이야기 니 용서 해주세요.
웹과 모든 브라우저는 CSS 픽셀이라는 단위로 1px를 정의합니다. CSS 픽셀은 실제 픽셀이 아니라 장치의 시야각을 기준으로 1/96 인치로 간주되는 단위입니다. 이것은 참조 픽셀 로 지정됩니다 .
참조 픽셀은 픽셀 밀도가 96dpi이고 판독기와의 거리가 팔 길이 인 장치에서 한 픽셀의 시각 각도입니다. 따라서 공칭 팔 길이가 28 인치 인 경우 시각 각도는 약 0.0213 도입니다. 팔 길이로 읽을 때 1px는 약 0.26mm (1/96 인치)에 해당합니다.
0.26mm의 공간에는 실제 장치 픽셀이 매우 많이있을 수 있습니다.
브라우저는 주로 레거시 이유로이 작업을 수행합니다. 웹이 탄생했을 때 대부분의 모니터는 96dpi 였지만 일관성을 위해 "예전에는"800x600의 15 인치 화면에 22px 버튼이 22px 버튼 크기의 두 배가되었습니다. 1600x1200의 15 인치 모니터. 이 경우 화면의 DPI는 실제로 2x (가로 해상도의 두 배이지만 동일한 물리적 공간에 있음)입니다. 이것은 웹과 앱에 좋지 않은 상황이므로 대부분의 운영 체제는 픽셀 값을 기기 독립 단위 (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 (내가 믿는 모바일 웹킷에서 처음)라는 개념을 도입했습니다.이를 통해 1 개의 CSS 픽셀을 대략 1 / 96 분의 1 인치이지만 이미지와 같은 자산의 크기가 두 배 여야 할 수도 있음을 이해하십시오. iPhone 시리즈를 살펴보면 모든 장치에서 CSS 픽셀 로 표시된 화면 너비 가 320px 라고 말합니다 . 사실이 아님을 알고 있습니다.
따라서 버튼을 CSS 공간에서 22px로 만들면 실제 화면의 표현은 22 * 장치 픽셀 비율입니다. 실제로 나는 이것을 말한다. 그것은 장치 픽셀 비율이 결코 정확하지 않기 때문에 정확히 이것이 아니다. 전화 제조업체는 2.1329857289918이 아닌 2.0, 3.0과 같은 좋은 숫자로 설정했다 ....
요약하면 CSS 픽셀은 장치에 독립적이며 화면의 물리적 크기와 디스플레이 밀도 등에 대해 걱정할 필요가 없습니다.
이야기의 교훈은 : 화면의 물리적 픽셀 크기를 이해하는 것에 대해 걱정하지 마십시오. 당신은 그것을 필요로하지 않습니다. 50px는 모든 모바일 장치에서 거의 동일하게 보이지만 약간 다를 수 있지만 CSS Pixel은 일관된 문서와 UI를 빌드하는 장치 독립적 인 방법입니다.
자원:
- 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
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.
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
<script>
var pixPer10CM = $('#meter').width();
var CMPerPix = 10 / pixPer10CM;
var widthCM = screen.width * CMPerPix;
alert(widthCM);
</script>
You can get that info with 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.
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
.
This is a database commonly used to detect device 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.
Here is more information and explanation about checking the physical size and resolution: http://www.scientiamobile.com/forum/viewtopic.php?f=16&t=286
I tackled this problem with one of my web projects http://www.vinodiscover.com The 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.
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.
http://www.quirksmode.org/blog/archives/2010/04/a_pixel_is_not.html
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
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 seems there 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).
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
).
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).
Using the getPPI() function (Mobile web: how to get physical pixel size?), to obtain a one inch id use this formula:
var ppi = getPPI();
var x = ppi * devicePixelRatio * screen.pixelDepth / 24;
$('#Cubo').width (x);
$('#Cubo').height(x);
<div id="Cubo" style="background-color:red;"></div>
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.
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.
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.
You can get screen DPI in JavaScript with window.devicePixelRatio . Or CSS query:
@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.
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:
<meta name="viewport" content="width=device-width, initial-scale=1">
$(window).width(); // returns width of browser viewport
$(document).width(); // returns width of HTML document
JqueryMobile Height of element
$(window).height(); // returns height of browser viewport
$(document).height(); // returns height of HTML document
Good Luck Danny117
You can get a rough estimation of size, but it's not accurate.
I've put together an example which I've tested on a couple devices to see what the results were. My iPhone 6 returns values about 33% larger. My 27" desktop monitor on my Mac reported as a 30" monitor.
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);
'Programing' 카테고리의 다른 글
SSL : 오류 : 0B080074 : x509 인증서 루틴 : X509_check_private_key : 키 값 불일치 (0) | 2020.09.23 |
---|---|
RVM을 사용하여 Rails on Lion을 설치할 수없는 이유는 무엇입니까? (0) | 2020.09.22 |
오류 : __karma __. start 메소드를 구현하는 일부 어댑터를 포함해야합니다. (0) | 2020.09.22 |
Symfony 2.8, 3.0 이상에서 buildForm ()에 데이터 전달 (0) | 2020.09.22 |
Vue-객체 배열을 깊이 관찰하고 변화를 계산합니까? (0) | 2020.09.22 |