Je travaille sur une sorte d'application unique qui doit générer des images à des résolutions spécifiques en fonction du périphérique sur lequel elles sont affichées. La sortie est donc différente sur un navigateur Windows classique (96 ppp), un iPhone (163 ppp), Android G1 (180 ppp) et d'autres appareils. Je me demande s'il y a un moyen de détecter cela automatiquement.
Ma recherche initiale semble dire non. La seule suggestion que j’ai vue est de créer un élément dont la largeur est définie par "1in" en CSS, puis de vérifier son offsetWidth (voir aussi Comment accéder aux paramètres de résolution de l’affichage à l’écran via javascript? ). Cela a du sens, mais iPhone me ment avec cette technique, disant que c'est 96 ppp.
Une autre approche pourrait consister à obtenir les dimensions de l’affichage en pouces, puis à les diviser par la largeur en pixels, mais je ne suis pas sûr de savoir comment procéder non plus.
Il existe la requête multimédia resolution
CSS - elle vous permet de limiter les styles CSS à des résolutions spécifiques:
Cependant, il n’est supporté que par Firefox 3.5 et versions ultérieures, Opera 9 et versions ultérieures, et IE 9 . Les autres navigateurs n’appliqueront pas du tout vos styles spécifiques à la résolution (bien que je n’aie pas vérifié les navigateurs autres que les ordinateurs de bureau).
<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>
attrapé à partir d'ici http://www.infobyip.com/detectmonitordpi.php . Fonctionne sur les appareils mobiles! (Android 4.2.2 testé)
Je suis venu avec un moyen qui ne nécessite pas le DOM ... du tout
Le DOM peut être compliqué, vous obligeant à ajouter des éléments au corps sans savoir ce qui se passe avec width: x !important
dans votre feuille de style. Vous devez également attendre que le DOM soit prêt à être utilisé ...
// 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)
Voici ce qui fonctionne pour moi (mais je ne l'ai pas testé sur les téléphones mobiles):
<body><div id="ppitest" style="width:1in;visible:hidden;padding:0px"></div></body>
Ensuite, je mets dans le .js: screenPPI = document.getElementById('ppitest').offsetWidth;
Cela m'a valu 96, ce qui correspond à la ppi de mon système.
J'avais également besoin d'afficher la même image avec la même taille à différents dpi d'écran, mais uniquement pour Windows IE. J'ai utilisé:
<img src = "image.jpg" style = " hauteur: expression (scale (438, 192)); width: expression (scale (270, 192))" /> échelle de fonctions (x, dpi) { // dpi est pour les dimensions d'origine de l'image renvoyer x * screen.deviceXDPI/dpi; }
Dans ce cas, la largeur/hauteur de l'image d'origine est 270 et 438 et l'image a été développée sur un écran de 192 dpi. screen.deviceXDPI n'est pas défini dans Chrome et la fonction de balance devra être mise à jour pour prendre en charge les navigateurs autres que IE.
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);
}
(De VodaFone)
La réponse de @Endless est plutôt bonne, mais pas lisible du tout, C'est une approche similaire avec min/max fixe (ça devrait être bien)
var dpi = (function () {
for (var i = 56; i < 2000; i++) {
if (matchMedia("(max-resolution: " + i + "dpi)").matches === true) {
return i;
}
}
return i;
})();
matchMedia est maintenant bien pris en charge et devrait donner de bons résultats, voir http://caniuse.com/#feat=matchmedia
Attention, le navigateur ne vous donnera pas le dpi exact de l'écran mais seulement une approximation
Je viens de trouver ce lien: http://dpi.lv/ . Il s'agit essentiellement d'un outil Web permettant de connaître la résolution de l'appareil client, les dpi et la taille de l'écran.
Je me suis rendu sur mon ordinateur et mon téléphone portable et il fournit la résolution et le DPI corrects pour moi. Il y a un repo github pour cela, vous pouvez donc voir comment cela fonctionne.
Le DPI est par définition lié à la taille physique de l'écran. Ainsi, vous ne pourrez pas avoir le vrai DPI sans connaître exactement le matériel derrière.
Les systèmes d’exploitation modernes ont convenu d’une valeur commune afin d’avoir des écrans compatibles: 96 dpi. C'est dommage mais c'est un fait.
Vous devrez vous fier au sniffing pour pouvoir deviner la taille réelle de l'écran nécessaire au calcul de la résolution (DPI = PixelSize/ScreenSize).
Je pense que votre meilleure approche consiste à combiner la suggestion de l'image "renifleur" avec une matrice de DPI connus pour les périphériques (via l'agent utilisateur et d'autres méthodes). Ce ne sera pas exact et ce sera difficile à maintenir, mais sans en savoir plus sur l'application que vous essayez de faire, c'est la meilleure suggestion que je puisse offrir.
Générez une liste des DPI connus: https://stackoverflow.com/a/6793227
Détectez le périphérique exact. En utilisant quelque chose comme:
navigator.userAgent.toLowerCase();
Par exemple, lors de la détection de mobile:
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());
Et profit!
Tu ne peux rien faire d'autre? Par exemple, si vous générez une image devant être reconnue par une caméra (par exemple, si vous exécutez votre programme, passez votre téléphone portable sur une caméra, la magie opère), ne pouvez-vous pas utiliser un format indépendant de la taille?
S'il s'agit d'une application à déployer dans des environnements contrôlés, pouvez-vous fournir un utilitaire d'étalonnage? (vous pouvez faire quelque chose de simple, comme imprimer des cartes de visite avec une petite règle, l'utiliser pendant le processus de calibrage).