web-dev-qa-db-fra.com

Obtenir la vraie largeur et la hauteur d'une image avec JavaScript? (dans Safari / Chrome)

Je crée un plugin jQuery.

Comment obtenir de la largeur et de la hauteur d'une image réelle avec Javascript dans Safari?

Les travaux suivants avec Firefox 3, IE7 et Opera 9:

var pic = $("img")

// need to remove these in of case img-element has set width and height
pic.removeAttr("width"); 
pic.removeAttr("height");

var pic_real_width = pic.width();
var pic_real_height = pic.height();

Mais dans les navigateurs Webkit tels que Safari et Google Chrome, les valeurs sont 0.

274
Frank Bannister

Les navigateurs Webkit définissent les propriétés height et width après le chargement de l'image. Au lieu d'utiliser des délais d'attente, je vous recommande d'utiliser l'événement onload d'une image. Voici un exemple rapide:

var img = $("img")[0]; // Get my img elem
var pic_real_width, pic_real_height;
$("<img/>") // Make in memory copy of image to avoid css issues
    .attr("src", $(img).attr("src"))
    .load(function() {
        pic_real_width = this.width;   // Note: $(this).width() will not
        pic_real_height = this.height; // work for in memory images.
    });

Pour éviter les effets que CSS pourrait avoir sur les dimensions de l'image, le code ci-dessus crée une copie en mémoire de l'image. C'est une solution très intelligente suggérée par FDisk .

Vous pouvez également utiliser les attributs naturalHeight et naturalWidth HTML5.

351
Xavi

Utilisez les attributs naturalHeight et naturalWidth de HTML5 .

Par exemple:

var h = document.querySelector('img').naturalHeight;

Fonctionne dans IE9 +, Chrome, Firefox, Safari et Opera ( stats ).

280
sandstrom

function getOriginalWidthOfImg(img_element) {
    var t = new Image();
    t.src = (img_element.getAttribute ? img_element.getAttribute("src") : false) || img_element.src;
    return t.width;
}

Vous n'avez pas besoin de supprimer le style des attributs image ou dimensions de l'image. Créez simplement un élément avec javascript et obtenez la largeur de l'objet créé.

60
FDisk

Le problème fondamental est que les navigateurs WebKit (Safari et Chrome) chargent les informations JavaScript et CSS en parallèle. Ainsi, JavaScript peut s'exécuter avant que les effets de style de CSS aient été calculés, renvoyant la mauvaise réponse. Dans jQuery, j'ai trouvé que la solution consiste à attendre jusqu'à ce que document.readyState == 'complete', .e.g.,

jQuery(document).ready(function(){
  if (jQuery.browser.safari && document.readyState != "complete"){
    //console.info('ready...');
    setTimeout( arguments.callee, 100 );
    return;
  } 
  ... (rest of function) 

En ce qui concerne la largeur et la hauteur ... en fonction de ce que vous faites, vous souhaiterez peut-être offsetWidth et offsetHeight, qui incluent des éléments tels que des bordures et du remplissage.

16
Cugel

Dans la réponse acceptée, il est beaucoup question du problème suivant: l’événement onload ne se déclenche pas si une image est chargée à partir du cache WebKit.

Dans mon cas, onload se déclenche pour les images en cache, mais la hauteur et la largeur sont toujours égales à 0. Un simple setTimeout résout le problème pour moi:

$("img").one("load", function(){
    var img = this;
    setTimeout(function(){
        // do something based on img.width and/or img.height
    }, 0);
});

Je ne peux pas dire pourquoi l'événement onload se déclenche même lorsque l'image est chargée à partir du cache (amélioration de jQuery 1.4/1.5?) - mais si vous rencontrez toujours ce problème, peut-être une combinaison de mes répondre et la technique var src = img.src; img.src = ""; img.src = src; fonctionnera.

(Notez que pour mes besoins, les dimensions prédéfinies ne me préoccupent pas, ni dans les attributs de l'image ni dans les styles CSS - mais vous pouvez vouloir les supprimer, comme indiqué dans la réponse de Xavi. Ou cloner l'image.)

16
JKS

cela fonctionne pour moi (safari 3.2), en tirant de l'intérieur de l'événement window.onload:

$(window).load(function() {
  var pic = $('img');

  pic.removeAttr("width"); 
  pic.removeAttr("height");

  alert( pic.width() );
  alert( pic.height() );
});
11
Owen

Vous pouvez obtenir l’image par programme et vérifier les dimensions à l’aide de Javascript sans avoir à manipuler le DOM.

var img = new Image();
img.onload = function() {
  console.log(this.width + 'x' + this.height);
}
img.src = 'http://www.google.com/intl/en_ALL/images/logo.gif';
8
Yëco

Qu'en est-il des propriétés image.naturalHeight et image.naturalWidth?

Semble fonctionner correctement avec plusieurs versions de Chrome, Safari et Firefox, mais pas du tout dans IE8 ou même dans IE9.

6
Andrew Mackenzie

Comment obtenir de vraies dimensions réelles sans clignoter image réelle:

(function( $ ){
   $.fn.getDimensions=function(){
         alert("First example:This works only for HTML code without CSS width/height definition.");
         w=$(this, 'img')[0].width;
         h=$(this, 'img')[0].height;

         alert("This is a width/height on your monitor: " + $(this, 'img')[0].width+"/"+$(this, 'img')[0].height);

         //This is bad practice - it shows on your monitor
         $(this, 'img')[0].removeAttribute( "width" );
         $(this, 'img')[0].removeAttribute( "height" );
         alert("This is a bad effect of view after attributes removing, but we get right dimensions: "+  $(this, 'img')[0].width+"/"+$(this, 'img')[0].height);
         //I'am going to repare it
         $(this, 'img')[0].width=w;
         $(this, 'img')[0].height=h;
         //This is a good practice - it doesn't show on your monitor
         ku=$(this, 'img').clone(); //We will work with a clone
         ku.attr( "id","mnbv1lk87jhy0utrd" );//Markup clone for a final removing
         ku[0].removeAttribute( "width" );
         ku[0].removeAttribute( "height" );
         //Now we still get 0
         alert("There are still 0 before a clone appending to document: "+ $(ku)[0].width+"/"+$(ku)[0].height);
         //Hide a clone
         ku.css({"visibility" : "hidden",'position':'absolute','left':'-9999px'}); 
         //A clone appending
         $(document.body).append (ku[0]);
         alert("We get right dimensions: "+ $(ku)[0].width+"/"+$(ku)[0].height);
         //Remove a clone
         $("#mnbv1lk87jhy0utrd").remove();

         //But a next resolution is the best of all. It works in case of CSS definition of dimensions as well.
         alert("But if you want to read real dimensions for image with CSS class definition outside of img element, you can't do it with a clone of image. Clone method is working with CSS dimensions, a clone has dimensions as well as in CSS class. That's why you have to work with a new img element.");
         imgcopy=$('<img src="'+ $(this, 'img').attr('src') +'" />');//new object 
         imgcopy.attr( "id","mnbv1lk87jhy0aaa" );//Markup for a final removing
         imgcopy.css({"visibility" : "hidden",'position':'absolute','left':'-9999px'});//hide copy 
         $(document.body).append (imgcopy);//append to document 
         alert("We get right dimensions: "+ imgcopy.width()+"/"+imgcopy.height());
         $("#mnbv1lk87jhy0aaa").remove();


   }
})( jQuery );

$(document).ready(function(){

   $("img.toreaddimensions").click(function(){$(this).getDimensions();});
});

Cela fonctionne avec <img class = "toreaddimensions" ...

5
Fox

Jquery a deux propriétés appelées naturalWidth et naturalHeight, que vous pouvez utiliser de cette façon.

$('.my-img')[0].naturalWidth 
$('.my-img')[0].naturalHeight

Où my-img est un nom de classe utilisé pour sélectionner mon image.

4
Samuel Santos

Comme indiqué précédemment, réponse Xavi ne fonctionnera pas si les images sont dans le cache. Le problème concerne Webkit qui ne déclenche pas l'événement de chargement sur les images en cache. Par conséquent, si les attributs Largeur/Hauteur ne sont pas définis explicitement dans la balise img, le seul moyen fiable d'obtenir les images consiste à attendre l'événement window.load. être congédié.

L'événement window.load se déclenchera toujours , vous pouvez donc accéder en toute sécurité à la largeur/hauteur de et img sans aucune astuce.

$(window).load(function(){

   //these all work

   $('img#someId').css('width');
   $('img#someId').width();
   $('img#someId').get(0).style.width;
   $('img#someId').get(0).width; 

});

Si vous devez obtenir la taille des images chargées dynamiquement pouvant être mises en cache (précédemment chargées), vous pouvez utiliser la méthode Xavi avec une chaîne de requête pour déclencher une actualisation du cache. L'inconvénient est que cela provoquera une autre demande au serveur, pour un img déjà mis en cache et qui devrait déjà être disponible. Webkit stupide.

var pic_real_width   = 0,
    img_src_no_cache = $('img#someId').attr('src') + '?cache=' + Date.now();

$('<img/>').attr('src', img_src_no_cache).load(function(){

   pic_real_width = this.width;

});

ps: si vous avez déjà un QueryString dans le img.src, vous devrez l'analyser et ajouter le paramètre supplémentaire pour effacer le cache.

3
xmarcos
$("#myImg").one("load",function(){
  //do something, like getting image width/height
}).each(function(){
  if(this.complete) $(this).trigger("load");
});

Commentaire de Chris: http://api.jquery.com/load-event/

2
Jerome Jaglale

Ma situation est probablement un peu différente. Je change dynamiquement le src d'une image via javascript afin de m'assurer que la nouvelle image est redimensionnée proportionnellement pour s'adapter à un conteneur fixe (dans une galerie de photos). Au départ, je venais de supprimer les attributs de largeur et de hauteur de l'image après son chargement (via l'événement de chargement de l'image), puis de les réinitialiser après avoir calculé les dimensions préférées. Cependant, cela ne fonctionne pas dans Safari et éventuellement IE (je ne l'ai pas testé dans IE à fond, _, mais l'image ne s'affiche même pas, alors ...).

Quoi qu'il en soit, Safari conserve les dimensions de l'image précédente, de sorte que les dimensions ne dépassent toujours qu'une image. Je suppose que cela a quelque chose à voir avec le cache. La solution la plus simple consiste donc simplement à cloner l’image et à l’ajouter au DOM (il est important de l’ajouter au DOM pour obtenir les propriétés with et height). Attribuez à l'image une valeur de visibilité masquée (n'utilisez pas display none car cela ne fonctionnera pas). Après avoir obtenu les dimensions, supprimez le clone.

Voici mon code utilisant jQuery:

// Hack for Safari and others
// clone the image and add it to the DOM
// to get the actual width and height
// of the newly loaded image

var cloned, 
    o_width, 
    o_height, 
    src = 'my_image.jpg', 
    img = [some existing image object];

$(img)
.load(function()
{
    $(this).removeAttr('height').removeAttr('width');
    cloned = $(this).clone().css({visibility:'hidden'});
    $('body').append(cloned);
    o_width = cloned.get(0).width; // I prefer to use native javascript for this
    o_height = cloned.get(0).height; // I prefer to use native javascript for this
    cloned.remove();
    $(this).attr({width:o_width, height:o_height});
})
.attr(src:src);

Cette solution fonctionne dans tous les cas.

2
Duane Comeaux

Comme le dit Luke Smith, le chargement des images est un désordre . Ce n'est pas fiable sur tous les navigateurs. Ce fait m'a fait très mal. Une image en cache ne déclenche pas du tout l'événement dans certains navigateurs. Par conséquent, ceux qui ont déclaré que "le chargement d'image est supérieur à setTimeout" sont faux.

La solution de Luke Smith est ici.

Et il y a ne discussion intéressante sur la façon dont ce désordre pourrait être géré dans jQuery 1.4.

J'ai trouvé qu'il est assez fiable de définir la largeur sur 0, puis d'attendre que la propriété "complete" devienne vraie et que la propriété width soit supérieure à zéro. Vous devez également surveiller les erreurs.

2
Nosredna

J'ai effectué une fonction de solution de contournement en utilisant le plugin imagesLoaded jquery: https://github.com/desandro/imagesloaded

            function waitForImageSize(src, func, ctx){
                if(!ctx)ctx = window;
                var img = new Image();
                img.src = src;
                $(img).imagesLoaded($.proxy(function(){
                    var w = this.img.innerWidth||this.img.naturalWidth;
                    var h = this.img.innerHeight||this.img.naturalHeight;
                    this.func.call(this.ctx, w, h, this.img);
                },{img: img, func: func, ctx: ctx}));
            },

Vous pouvez l'utiliser en passant l'URL, la fonction et son contexte. La fonction est exécutée une fois l'image chargée et renvoyée à l'image créée, ainsi que sa largeur et sa hauteur.

waitForImageSize("image.png", function(w,h){alert(w+","+h)},this)
1
Zdeněk Mlčoch

Récemment, j’avais besoin de trouver la largeur et la hauteur pour définir la taille par défaut du graphique représentant .dialog. La solution que j'ai utilisée était:

 graph= $('<img/>', {"src":'mySRC', id:'graph-img'});
    graph.bind('load', function (){
        wid = graph.attr('width');
        hei = graph.attr('height');

        graph.dialog({ autoOpen: false, title: 'MyGraphTitle', height:hei, width:wid })
    })

Pour moi, cela fonctionne dans FF3, Opera 10, IE 8,7,6

P.S. Vous trouverez peut-être d'autres solutions en regardant à l'intérieur de plugins comme LightBox ou ColorBox

1
SDemonUA

Si l'image est déjà utilisée, vous devez:

  1. définir les simulations d'image sur initial

    image.css ('width', 'initial'); image.css ('hauteur', 'initiale');

  2. obtenir des dimensions

    var originalWidth = $ (this) .width (); var originalHeight = $ (this) .height ();

1
Sebastián Rojas

Vous pouvez utiliser les propriétés naturalWidth et naturalHeight de l'élément image HTML. (Voici plus info ).

Vous l'utiliseriez comme ceci:

//you need a reference to the DOM element, not a jQuery object. It would be better if you can use document.getElementByTagsName or ID or any other native method
var pic = $("img")[0];
var pic_real_width = pic.naturalWidth;
var pic_real_height = pic.naturalHeight;

Il semble que cela fonctionne dans tous les navigateurs sauf sur IE à partir de la version 8 et inférieure.

1
Jair Reina

Cela fonctionne à la fois pour les images en cache et celles chargées dynamiquement.

function LoadImage(imgSrc, callback){
  var image = new Image();
  image.src = imgSrc;
  if (image.complete) {
    callback(image);
    image.onload=function(){};
  } else {
    image.onload = function() {
      callback(image);
      // clear onLoad, IE behaves erratically with animated gifs otherwise
      image.onload=function(){};
    }
    image.onerror = function() {
        alert("Could not load image.");
    }
  }
}

Pour utiliser ce script:

function AlertImageSize(image) {
  alert("Image size: " + image.width + "x" + image.height);
}
LoadImage("http://example.org/image.png", AlertImageSize);

Démo: http://jsfiddle.net/9543z/2/

1
CheeseSucker

Il existe maintenant un plugin jQuery, event.special.load, pour traiter les cas où l'événement de chargement sur une image en cache ne se déclenche pas: http://github.com/peol/jquery.imgloaded/raw/ master/ahpi.imgload.js

1
S P

Pour ajouter à la réponse de Xavi, github de Paul Irish Le gitgub de David Desandro propose une fonction appelée imagesLoaded () qui fonctionne sur les mêmes principes et contourne le problème des images en cache de certains navigateurs qui ne déclenchent pas l'événement .load () (avec astucieux original_src -> data_uri - > commutation originale_src).

Il est largement utilisé et mis à jour régulièrement, ce qui contribue à en faire la solution la plus robuste au problème, IMO.

1
RobW

Je suis tombé sur ce fil en essayant de trouver une réponse à ma propre question. J'essayais d'obtenir la largeur/hauteur d'une image dans une fonction APRÈS le chargeur, et je n'arrêtais pas d'arriver avec 0. Je pense que c'est peut-être ce que vous cherchez, car cela fonctionne pour moi:

tempObject.image = $('<img />').attr({ 'src':"images/prod-" + tempObject.id + ".png", load:preloader });
xmlProjectInfo.Push(tempObject);

function preloader() {
    imagesLoaded++;
    if (imagesLoaded >= itemsToLoad) { //itemsToLoad gets set elsewhere in code
        DetachEvent(this, 'load', preloader); //function that removes event listener
        drawItems();
    }   
}

function drawItems() {
    for(var i = 1; i <= xmlProjectInfo.length; i++)
        alert(xmlProjectInfo[i - 1].image[0].width);
}
0
Stephen Synowsky
$(document).ready(function(){
                            var image = $("#fix_img");
                            var w = image.width();
                            var h = image.height();
                            var mr = 274/200;
                            var ir = w/h
                            if(ir > mr){
                                image.height(200);
                                image.width(200*ir);
                            } else{
                                image.width(274);
                                image.height(274/ir);
                            }
                        }); 

// Ce code permet d'afficher une image de dimension 200 * 274.

0
Eranda

J'ai vérifié la réponse de Dio et cela fonctionne très bien pour moi.

$('#image').fadeIn(10,function () {var tmpW = $(this).width(); var tmpH = $(this).height(); });

Assurez-vous que vous appelez toutes vos fonctions. cette poignée avec la taille de l'image dans la fonction de rappel de fadeIn ().

Merci pour cela.

0
drublic

Découvrez ce dépôt dans github!

Excellent exemple pour vérifier la largeur et la hauteur en utilisant Javascript

https://github.com/AzizAK/ImageRealSize

--- Edited est demandé à partir de quelques commentaires.

Code Javascript:

 function CheckImageSize(){
var image = document.getElementById("Image").files[0];
           createReader(image, function (w, h) {

                alert("Width is: " + w + " And Height is: "+h);
});            
}


  function  createReader(file, whenReady) {
        var reader = new FileReader;
        reader.onload = function (evt) {
            var image = new Image();
            image.onload = function (evt) {
                var width = this.width;
                var height = this.height;
                if (whenReady) whenReady(width, height);
            };
            image.src = evt.target.result;
        };
        reader.readAsDataURL(file);
    }

et code HTML:

<html>
<head>
<title>Image Real Size</title>
<script src="ImageSize.js"></script>
</head>
<body>
<input type="file" id="Image"/>
<input type="button" value="Find the dimensions" onclick="CheckImageSize()"/>
</body>
<html>
0

Une autre suggestion consiste à utiliser plugin imagesLoaded .

$("img").imagesLoaded(function(){
alert( $(this).width() );
alert( $(this).height() );
});
0
gadelkareem

Cela fonctionne multi-navigateur

var img = new Image();
$(img).bind('load error', function(e)
{
    $.data(img, 'dimensions', { 'width': img.width, 'height': img.height });                    
});
img.src = imgs[i];              

obtenir les dimensions en utilisant

$(this).data('dimensions').width;
$(this).data('dimensions').height;

À votre santé!

0
foxybagga

J'utilise une approche différente, il suffit d'appeler le serveur Ajax pour obtenir la taille de l'image lorsqu'un objet est utilisé.

//make json call to server to get image size
$.getJSON("http://server/getimagesize.php",
{"src":url},
SetImageWidth
);

//callback function
function SetImageWidth(data) {

    var wrap = $("div#image_gallery #image_wrap");

    //remove height
     wrap.find("img").removeAttr('height');
    //remove height
     wrap.find("img").removeAttr('width');

    //set image width
    if (data.width > 635) {
        wrap.find("img").width(635);
    }
    else {
         wrap.find("img").width(data.width);
    }
}

et bien sûr le code côté serveur:

<?php

$image_width = 0;
$image_height = 0;

if (isset ($_REQUEST['src']) && is_file($_SERVER['DOCUMENT_ROOT'] . $_REQUEST['src'])) {

    $imageinfo = getimagesize($_SERVER['DOCUMENT_ROOT'].$_REQUEST['src']);
    if ($imageinfo) {
       $image_width=  $imageinfo[0];
       $image_height= $imageinfo[1];
    }
}

$arr = array ('width'=>$image_width,'height'=>$image_height);

echo json_encode($arr);

?>
0
damijanc

Voici une solution multi-navigateurs qui déclenche un événement lorsque les images sélectionnées sont chargées: http://desandro.github.io/imagesloaded/ vous pouvez rechercher la hauteur et la largeur dans la fonction imagesLoaded ().

0
Paul Mason

Pour les fonctions pour lesquelles vous ne souhaitez pas modifier l'emplacement ou l'image d'origine.

$(this).clone().removeAttr("width").attr("width");
$(this).clone().removeAttr("height").attr("height);
0
Davin