AndroidのChromeで物理的な画面サイズ/ dpi /ピクセル密度を取得する


88

質問

AndroidのChromeで実際に正しい画面の物理的なサイズを取得する安全な方法はありますか?必要に応じて、古いバージョンのChromeとAndroidを対象外にすることができます。

事前調査

javascript(またはcss)内からデバイスの実際の物理的な画面サイズを取得することについて、stackoverflowに関する多くの行き止まりの質問があります。ブラウザの実装が正しい情報を提供するハードウェアに依存しているOSAPIに依存していることは言うまでもなく、htmlapiの標準化と実際のブラウザの実装の間に収束はないようです。

ちなみに、いくつかの以前の答えは、当時普及していた特定のピクセル密度を想定することで難解であり(2011年など)、したがって役に立たない。他のものはウェブキットに関連していますが、クロームブリンクはクローム(?)のウェブキットに取って代わったかもしれません。

Android上のChromeのみに制限することで、簡単なソリューションの存在を探りたいと思います。

注意

これはすべて、ブラウザー内のjavascript(またはcss)ソリューションに関するものであり、ネイティブアプリのソリューションではありません。


21
それは単に間違っています。私のユーザーインターフェイスは、ユーザーに表示されるボタンの大きさなどを知りたいと思っています。あなたはおそらくその中でコード開発者として考えすぎているかもしれません;)
matanster 2014

12
たとえば、ボタンのサイズは、ビューポートのパーセンテージではなく、タッチするのに十分な大きさである必要があります。それが高品質のデザインにとってどのように意味があるのか​​わかりません。
マタンスター2014

16
@mattは絶対に正しいです。特に太い指の世界でのWebUX / UIの最も重要な側面の1つは、ボタンがポインター(この場合は指)に適切であると同時に、表示距離に適したサイズになっていることを確認することです。画面から目へ。モバイルデバイスのこの新しい領域は問題を複雑にしているため、物理的な画面サイズの検出はさらに重要です。
ジェイソンTフェザリンガム2014年

7
私はあなたと100%@ mattです。MozillaとGoogleが、デバイスの1インチあたりwindow.screenDensity物理ピクセルを含むJavaScriptプロパティを提供できない理由がわかりません。マットは、そこから取得できます。window.screenHeightそしてwindow.screenWidth物理ミリメートルで、あまりにもいいだろう。
trusktr 2014

7
@Kinlan物理的な画面サイズは一般的に重要です。これが、現時点でネイティブ開発がWeb開発よりも強力である理由です。ネイティブ環境では、たとえば、最近のすべてのデバイスで、幅が1(実世界)インチのボタンを作成できます。私の知る限り、これは現在Web環境では不可能です。私は何かを逃したことがありますか?
trusktr 2014

回答:


118

実際の物理的寸法や実際のDPIを実際に取得することはできません。また、取得できたとしても、それらを使用して何もすることはできません。

これはかなり長くて複雑な話なので、許してください。

Webおよびすべてのブラウザーは、1pxをCSSピクセルと呼ばれる単位として定義します。CSSピクセルは実際のピクセルではなく、デバイスの視野角に基づいて1/96インチと見なされる単位です。これは、参照ピクセルとして指定されます。

参照ピクセルは、ピクセル密度が96dpiで、アームの長さのリーダーからの距離を持つデバイス上の1ピクセルの視角です。したがって、公称アームの長さが28インチの場合、視角は約0.0213度になります。したがって、腕の長さで読み取る場合、1pxは約0.26 mm(1/96インチ)に相当します。

0.26mmのスペースでは、実際のデバイスピクセルが非常に多くなる可能性があります。

ブラウザは主にレガシーの理由でこれを行います-ほとんどのモニターはウェブが生まれたとき96dpiでした-しかし一貫性のために、「昔」では、800x600の15インチ画面の22pxボタンは上の22pxボタンの2倍のサイズでした1600x1200の15インチモニター。この場合、画面のDPIは実際には2倍です(水平方向の解像度は2倍ですが、同じ物理空間内にあります)。これはウェブとアプリにとって悪い状況であるため、ほとんどのオペレーティングシステムは、ピクセル値をデバイスに依存しないユニット(AndroidのDIPS、iOSのPT 、ウェブのCSSピクセル)に抽象化する多くの方法を考案しました

iPhone Safariブラウザは(私の知る限り)ビューポートの概念を最初に導入したものです。これは、フルデスクトップスタイルのアプリケーションを小さな画面でレンダリングできるようにするために作成されました。ビューポートの幅は960pxに定義されています。これは基本的にページを3倍にズームアウトしたため(iphoneは元々320pxでした)、1CSSピクセルは物理ピクセルの1/3です。ビューポートを定義すると、このデバイスを163dpiで1CSSピクセル= 1実ピクセルに一致させることができます。

幅が「デバイス幅」のビューポートを使用することで、デバイスごとにビューポートの幅を最適なCSSピクセルサイズに設定する必要がなくなり、ブラウザが自動的に設定します。

ダブルDPIデバイスの導入により、携帯電話メーカーはモバイルページが50%小さく表示されることを望まなかったため、devicePixelRatio(私が信じるモバイルWebキットで最初)と呼ばれる概念を導入しました。これにより、1つのCSSピクセルを約1 /に保つことができます。 96分の1インチですが、画像などのアセットは2倍のサイズが必要になる場合があることを理解してください。iPhoneシリーズを見ると、すべてのデバイスで、CSSピクセル単位の画面の幅は320ピクセルであると言われていますが、これは正しくないことがわかっています。

したがって、CSSスペースでボタンを22ピクセルにした場合、物理画面での表現は22 *デバイスピクセル比になります。実際、私はこれを言いますが、デバイスのピクセル比も正確ではないため、正確にはこれではありません。電話メーカーは、2.1329857289918ではなく2.0、3.0などの適切な数値に設定しています。

要約すると、CSSピクセルはデバイスに依存しないため、画面の物理的なサイズや表示密度などについて心配する必要はありません。

話の教訓は次のとおりです。画面の物理的なピクセルサイズを理解することを心配しないでください。あなたはそれを必要としません。50pxは、すべてのモバイルデバイスでほぼ同じように見えるはずですが、少し異なる場合がありますが、CSS Pixelは、一貫性のあるドキュメントとUIを構築するためのデバイスに依存しない方法です。

リソース:


1
@mattタブレットでも同じです。RetinaMacの本と同じように。目標は、特にビューポートwidth = device-widthを設定した場合、「CSSピクセル」がすべてのプラットフォームで比較的均一になることです。
キンラン2014

14
あなたは「彼らとは何もできない」と言った。同意しません。その情報を使用して、高さが常に16ポイント(実際のインチの16/72)になるフォントを設定できます。これは非常に貴重であり、ネイティブ開発がWeb開発よりも強力であり続ける理由の1つです。
trusktr 2014

8
実際、ピクセル単位の実際の画面サイズの完全に合理的な使用法は、適切な解像度で背景画像をレンダリングすることです。
WhyNotHugo 2015年

2
「50pxはすべてのモバイルデバイスでほぼ同じように見えるはずです」たとえば、1200x1920の4インチの電話と1000x600の10インチのタブレットを並べて使用することを証明してください。
iloveregex 2016

6
また、「何もできない」という意見にも同意しません。デバイスが携帯電話なのかタブレットなのかを確実に検出し、ユーザーが指で画面の上を簡単に指さすことができると想定できます。
ブライアンキャナード2018年

11

マットの答えに基づいて、私はテストを行いました:

// 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ブラウザで実際の物理的な値を取得する方法はまだないようです。


あなたがどの答えを参照しているのかわかりませんが(「マット」はどこにも表示されません)、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で始まり、ハイエンド画面は200dpiであるため。カットオフはおそらくその中間です。」
マイク

1
他のネイティブアプリケーションと同じように、ブラウザはデバイスドライバによってOSに提供されるOSAPIを介してデバイスの解像度を取得できると思います。精度はこの情報に依存します。
マイク

ただし、デバイスの解像度は実際の物理的な寸法と同じではありません。14インチのラップトップと15インチのラップトップの解像度は同じである可能性があります。
ジェイクウィルソン

6
番号!できません。Cssの10cmは実際には異なるサイズになります。それが実際に10cm、12cm、または7cmになるかどうかは、運の問題です。ブラウザは常に1インチあたりのピクセル数(dpi)のように動作するため、このソリューションに基づく私のjsfiddleデモは次のとおり
Dariusz Sikorski

5

あなたはWURFLでその情報を得ることができます:

デバイスの表示プロパティ

属性は次のように呼ばれます。

resolution_(width|height)

physical_display_(width|height)

ロングバージョン:

これを達成するための最良かつ最も信頼できる戦略はuser agent string、ブラウザからWURFL、必要な情報を提供できる最新のDBのような(または別の)DBに送信することです。

ユーザーエージェント文字列

これは、最新のすべてのブラウザが提供できる情報です。デバイスとそのOSに関する情報を公開します。のような辞書の助けがなければ、アプリケーションにとって十分な意味がありませんWURFL

WURFL

これは、デバイスのプロパティを検出するために一般的に使用されるデータベースです。

これを使用すると、市場で人気のあるデバイスのほとんどを正確にサポートできる可能性があります。コードデモを投稿しますが、WURFLサイトからダウンロードして入手できます。このようなデモは、ライブラリとともにダウンロードされるexamples / demoフォルダーにあります。

WURFLをダウンロード

物理的なサイズと解像度の確認に関する詳細と説明は次のとおりです。http//www.scientiamobile.com/forum/viewtopic.php?f = 16&t = 286


3

「この問題に対する適切な解決策はありません」という回答を補足するものとして、CSShttps ://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画面サイズと解像度に関係なく、同じサイズで何かを描画するために使用されます。これを念頭に置いてpxptまたはの少なくとも1つを期待することができますpc使用したい精度に関係なくピクセルレベルでの描画に使用できるできます(そうでない場合、数百万のピクセルを持つことのポイントは何ですか?)。うーん、ダメ。すべての単位はメートル単位の分数であり、これらの単位はすべて異なるスケールになっています。そして、話の中で最悪なのは、これらのどれも正確ではないという事実です。w3schoolsの例で遊んでください(20cmの線を引き、定規で測定します)。

だから、最後に: -そこに正確に物理的な大きさで何かを描画する方法は(とケースであるべきではありませんcmmmin、、最終的にptpc)。-画面サイズと解像度に関係なく、同じサイズで何かを描画する方法はありません(少なくともそうなるはずですpx)。

これは、実装の問題(実際の画面サイズが使用されていない)と設計の問題(pxそのためのユニットがすでに非常に多いのに、なぜ画面サイズに依存しない必要があるのか)の両方です。


2

私は自分のWebプロジェクトの1つでこの問題に取り組みました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ピクセル密度は約150ppiです。

これを考慮して、ピクセル密度に関係なく、幅が284px未満の場合に1列を表示するようにCSSを設定しました。次に、284pxと568pxの間の2つの列。次に、852pxより3列上。ブラウザがピクセル密度の計算を自動的に行うようになったため、見た目よりもはるかに簡単です。

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


3
ネイティブ開発では、正確な値を取得できます。ネイティブの場合は+ 1、Webの場合は-1。
trusktr 2014

Androidで正確な物理サイズを取得できますか?
アポロクラーク


2

WURFLを使用して解決策を見つけることについてのzehelvionの返信への応答として、WURFLはJavaScriptスニペットとしても利用できることにも言及する価値があります。

wurfl.ioで提供されている無料版では、画面と解像度に関する情報は得られません(デバイス名、フォームファクター、モバイル/モバイルではありません)が、ここで利用できるより多くの機能を備えた商用バージョンもあります


3
私はこれをその特定の答えへのコメントに含めることを提案します。
darkgaze 2016年

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 name="viewport" content="width=device-width, initial-scale=1">


0

要素のJqueryMobile幅

$(window).width();   // returns width of browser viewport
$(document).width(); // returns width of HTML document

JqueryMobile要素の高さ

$(window).height();   // returns height of browser viewport
$(document).height(); // returns height of HTML document

幸運ダニー117


3
これらは仮想ディメンションであり、必ずしも物理的な実世界のディメンションであるとは限りません。
trusktr 2014

おかげで私はそれを知りませんでした
danny117 2014

0

getPPI()関数(モバイルWeb:物理的なピクセルサイズを取得する方法?)を使用して、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その場合、私は....それの関連ここで計算する方法を疑問に思う、色深度とは関係ありません
matansterは

0

私がこれに答えることができればいいのですが、APIを構築するオタクは、基本的な必需品を提供せず、時には少し抽象化しすぎます。

ところで、私は40年のUIとソフトウェアデザインデザインの経験があり、「VESA」ドライバーの時代以前から永遠に見えるもののためにこれを持っていることを推進してきました:)。

タッチスクリーンの場合、ピクセル数が1cm(指の平均タッチ領域の直径に非常に近い)である「fingerSize()」と呼ばれるものがありましたが、ルートデータは「dpcm」です。

ディスプレイに必要なもう1つのものは、「画角」です。表示およびタッチ機能用のディスプレイデバイスのタイプは、表示距離をほぼ定義します。

    (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

サイズの概算は得られますが、正確ではありません。

結果がどうなるかを確認するために、いくつかのデバイスでテストした例をまとめました。私のiPhone6は約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 2016

私にとっても正確ではありません。問題はwindow.devicePixelRatio。によるものだと思います。Apple Thunderbolt画面では1、Macbook Pro Touchbar 15 "では2です。この値は常に整数ですか?比率であるため意味がありません。その他の要素:stackoverflow.com/questions/16385573/…
トム
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.