web-dev-qa-db-ja.com

JS / CSSからシステムDPI / PPIを検出しますか?

私は、それらが表示されるデバイスに応じて特定の解像度で画像を生成する必要がある一種のユニークなアプリに取り組んでいます。そのため、通常のWindowsブラウザー(96ppi)、iPhone(163ppi)、Android G1(180ppi)、およびその他のデバイスでは出力が異なります。これを自動的に検出する方法があるかどうか疑問に思います。

私の最初の研究はノーと言うようです。私が見た唯一の提案は、CSSで「1in」として幅が指定されている要素を作成し、そのoffsetWidthを確認することです( javascript経由で画面表示のDPI設定にアクセスする方法 も参照)。理にかなっていますが、iPhoneは96ppiだと言って、そのテクニックで私に嘘をついています。

別のアプローチとしては、ディスプレイの寸法をインチ単位で取得し、幅をピクセル単位で除算する方法もありますが、その方法もわかりません。

48
Josh Santangelo
<div id='testdiv' style='height: 1in; left: -100%; position: absolute; top: -100%; width: 1in;'></div>
<script type='text/javascript'>
  var devicePixelRatio = window.devicePixelRatio || 1;
  dpi_x = document.getElementById('testdiv').offsetWidth * devicePixelRatio;
  dpi_y = document.getElementById('testdiv').offsetHeight * devicePixelRatio;
  
  console.log(dpi_x, dpi_y);
</script>

ここから入手 http://www.infobyip.com/detectmonitordpi.php モバイルデバイスで動作します! (Android 4.2.2テスト済み)

13
MaxXx1313

resolution CSSメディアクエリがあります。これにより、CSSスタイルを特定の解像度に制限できます。

ただし、 Firefox 3.5以上でのみサポートされています。Opera 9以上、およびIE 9 。他のブラウザではサポートされません。解像度固有のスタイルをまったく適用します(ただし、デスクトップ以外のブラウザーはチェックしていません)。

11
Paul D. Waite

DOMを必要としない方法を思いついた...まったく

DOMは乱雑である可能性があり、width: x !importantスタイルシート。また、DOMが使用できるようになるまで待つ必要があります...

// Binary search, (faster then loop)
// also don't test every possible value, since it tries low, mid, and high
// http://www.geeksforgeeks.org/find-the-point-where-a-function-becomes-negative/
function findFirstPositive(b, a, i, c) {
  c=(d,e)=>e>=d?(a=d+(e-d)/2,0<b(a)&&(a==d||0>=b(a-1))?a:0>=b(a)?c(a+1,e):c(d,a-1)):-1
  for (i = 1; 0 >= b(i);) i *= 2
  return c(i / 2, i)|0
}


var dpi = findFirstPositive(x => matchMedia(`(max-resolution: ${x}dpi)`).matches)

console.log(dpi)
9
Endless

ここに私のために働くものがあります(ただし、携帯電話でテストしませんでした):

_<body><div id="ppitest" style="width:1in;visible:hidden;padding:0px"></div></body>
_

次に、.jsを挿入します:screenPPI = document.getElementById('ppitest').offsetWidth;

これで96になりました。これはシステムのppiに相当します。

6
john

また、同じ画像を異なる画面dpiで同じサイズで表示する必要がありましたが、それはWindows IEのみです。私は使用しました:

 <img src = "image.jpg" style = "
 height:expression(scale(438、192)); 
 width:expression(scale(270、192)) "/>

function scale(x、dpi){
 
 // dpiは画像の元の寸法を表します
 return x * screen .deviceXDPI/dpi; 
} 

この場合、元の画像の幅/高さは270と438で、画像は192dpiの画面で開発されました。 screen.deviceXDPIはChromeで定義されておらず、IE以外のブラウザをサポートするためにスケール関数を更新する必要があります

3
Farid Z
function getPPI(){
  // create an empty element
  var div = document.createElement("div");
  // give it an absolute size of one inch
  div.style.width="1in";
  // append it to the body
  var body = document.getElementsByTagName("body")[0];
  body.appendChild(div);
  // read the computed width
  var ppi = document.defaultView.getComputedStyle(div, null).getPropertyValue('width');
  // remove it again
  body.removeChild(div);
  // and return the value
  return parseFloat(ppi);
} 

(VodaFoneから)

2
TJS101

@Endlessからの返信はかなり良いですが、まったく読めません、これは固定された最小/最大の良いアプローチです(良いものでなければなりません)

var dpi = (function () {
    for (var i = 56; i < 2000; i++) {
        if (matchMedia("(max-resolution: " + i + "dpi)").matches === true) {
            return i;
        }
    }
    return i;
})();

matchMediaは現在十分にサポートされており、良好な結果が得られるはずです。 http://caniuse.com/#feat=matchmedia を参照してください。

ブラウザが正確な画面dpiを提供するのではなく、近似値のみを提供することに注意してください

2
jrmgx

次のリンクを見つけました: http://dpi.lv/ 。基本的には、クライアントデバイスの解像度、dpi、および画面サイズを検出するWebツールです。

コンピューターと携帯電話で訪問したところ、正しい解像度とDPIが得られました。 githubリポジトリがありますので、どのように機能するかを確認できます。

1
Adam

DPIは、定義上、ディスプレイの物理サイズに関連付けられています。そのため、背後のハードウェアを正確に知らないと、実際のDPIを取得できません。

最新のOSは、互換性のあるディスプレイを得るための共通の値である96 dpiに同意しました。それは残念ですが、それは事実です。

解像度の計算に必要な実際の画面サイズを推測できるようにするには、スニッフィングに依存する必要があります(DPI = PixelSize/ScreenSize)。

1
Vincent Robert

あなたの最善のアプローチは、「スニファー」イメージの提案を、デバイスの既知のDPIのマトリックスと結合することだと思います(ユーザーエージェントやその他の方法を使用)。それは正確ではなく、維持するのが苦痛になりますが、作成しようとしているアプリについて詳しく知ることなく、私が提供できる最高の提案です。

1
FriendOfFuture

既知のDPIのリストを生成します。 https://stackoverflow.com/a/6793227

正確なデバイスを検出します。次のようなものを使用します。

navigator.userAgent.toLowerCase();

たとえば、モバイルを検出する場合:

window.isMobile=/iphone|iPod|ipad|Android|blackberry|opera mini|opera mobi|skyfire|maemo|windows phone|Palm|iemobile|symbian|symbianos|fennec/i.test(navigator.userAgent.toLowerCase());

そして利益!

0
haelmic

他に何もできませんか?たとえば、カメラで認識される画像を生成している場合(つまり、プログラムを実行し、カメラで携帯電話をスワイプすると、魔法が発生します)、サイズに依存しない何かを使用できませんか?

これが制御された環境に展開されるアプリケーションである場合、キャリブレーションユーティリティを提供できますか? (小さな定規が入った名刺を印刷するような簡単なものを作成し、調整プロセスで使用できます)。

0
alex