Obter a largura real e a altura de uma imagem com JavaScript? (no Safari / Chrome)

Eu estou criando um plugin jQuery.

Como faço para obter largura e altura real da imagem com Javascript no Safari?

A seguir funciona com o Firefox 3, o IE7 e o 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(); 

Mas nos navegadores Webkit, como o Safari e o Google Chrome, os valores são 0.

    Os navegadores Webkit definem a propriedade height e width depois que a imagem é carregada. Em vez de usar tempos limite, recomendo usar o evento onload de uma imagem. Aqui está um exemplo rápido:

     var img = $("img")[0]; // Get my img elem var pic_real_width, pic_real_height; $("") // 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. }); 

    Para evitar qualquer um dos efeitos que o CSS possa ter nas dimensões da imagem, o código acima faz uma cópia na memory da imagem. Esta é uma solução muito inteligente sugerida pelo FDisk .

    Você também pode usar os naturalHeight e naturalWidth HTML5.

    Use os atributos naturalWidth e naturalWidth do HTML5 .

    Por exemplo:

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

    Funciona no IE9 +, Chrome, Firefox, Safari e Opera ( statistics ).

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

    Você não precisa remover o estilo dos atributos de dimensões da imagem ou imagem. Basta criar um elemento com javascript e obter a largura do object criado.

    O problema raiz é que os navegadores WebKit (Safari e Chrome) carregam informações JavaScript e CSS em paralelo. Assim, o JavaScript pode ser executado antes que os efeitos de estilo do CSS sejam computados, retornando a resposta errada. Em jQuery, descobri que a solução é esperar até document.readyState == ‘complete’, .eg,

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

    Quanto a largura e altura … dependendo do que você está fazendo, você pode querer offsetWidth e offsetHeight, que incluem coisas como bordas e preenchimento.

    Há muita discussão na resposta aceita sobre um problema em que o evento onload não é acionado se uma imagem é carregada do cache do WebKit.

    No meu caso, o onload triggers para imagens em cache, mas a altura e a largura ainda são 0. Um simples setTimeout resolveu o problema para mim:

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

    Eu não posso falar por que o evento onload está triggersndo mesmo quando a imagem é carregada do cache (melhoria do jQuery 1.4 / 1.5?) – mas se você ainda estiver enfrentando esse problema, talvez uma combinação da minha resposta e do var src = img.src; img.src = ""; img.src = src; var src = img.src; img.src = ""; img.src = src; técnica vai funcionar.

    (Note que, para os meus propósitos, não estou preocupado com as dimensões predefinidas, seja nos atributos da imagem ou nos estilos CSS – mas você pode querer removê-las, de acordo com a resposta de Xavi. Ou clonar a imagem.)

    isso funciona para mim (Safari 3.2), triggersndo de dentro do evento window.onload :

     $(window).load(function() { var pic = $('img'); pic.removeAttr("width"); pic.removeAttr("height"); alert( pic.width() ); alert( pic.height() ); }); 

    Você pode obter a imagem programaticamente e verificar as dimensões usando JavaScript sem precisar mexer no 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'; 

    Como obtemos dimensões reais certas sem uma imagem real intermitente:

     (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=$('');//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();}); }); 

    Ele funciona com

    E quanto image.naturalWidth propriedades image.naturalWidth e image.naturalWidth ?

    Parece funcionar bem em algumas versões no Chrome, Safari e Firefox, mas não no IE8 ou mesmo no IE9.

    Jquery tem duas propriedades chamadas naturalWidth e naturalHeight, você pode usar desta maneira.

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

    Onde my-img é um nome de class usado para selecionar minha imagem.

    Como dito anteriormente, a resposta do Xavi não funcionará se as imagens estiverem no cache. O problema responde ao webkit não triggersr o evento de carregamento em imagens em cache, portanto, se os attrs width / height não estiverem definidos explicitamente na tag img, a única maneira confiável de obter as imagens é aguardar o evento window.load ser triggersdo. .

    O evento window.load será window.load sempre , portanto, é seguro acessar a largura / altura e img depois disso sem qualquer truque.

     $(window).load(function(){ //these all work $('img#someId').css('width'); $('img#someId').width(); $('img#someId').get(0).style.width; $('img#someId').get(0).width; }); 

    Se você precisar obter o tamanho das imagens carregadas dinamicamente que podem ser armazenadas em cache (carregadas anteriormente), será possível usar o método Xavi mais uma cadeia de consulta para acionar uma atualização de cache. A desvantagem é que ele causará outra solicitação ao servidor, para uma img já armazenada em cache e que já deve estar disponível. Webkit estúpido.

     var pic_real_width = 0, img_src_no_cache = $('img#someId').attr('src') + '?cache=' + Date.now(); $('').attr('src', img_src_no_cache).load(function(){ pic_real_width = this.width; }); 

    ps: se você já tem um QueryString no img.src , você terá que analisá-lo e adicionar o param extra para limpar o cache.

    Como Luke Smith diz, a carga de imagem é uma bagunça . Não é confiável em todos os navegadores. Este fato me deu muita dor. Uma imagem em cache não irá triggersr o evento em alguns navegadores, então aqueles que disseram que “o carregamento da imagem é melhor que o setTimeout” estão errados.

    A solução de Luke Smith está aqui.

    E há uma discussão interessante sobre como essa bagunça pode ser tratada no jQuery 1.4.

    Eu descobri que é bastante confiável definir a largura como 0, depois esperar que a propriedade “complete” seja verdadeira e que a propriedade de largura seja maior que zero. Você também deve procurar erros.

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

    Do comentário de Chris: http://api.jquery.com/load-event/

    Minha situação é provavelmente um pouco diferente. Estou mudando dinamicamente o src de uma imagem via javascript e necessário para garantir que a nova imagem seja dimensionada proporcionalmente para caber em um contêiner fixo (em uma galeria de fotos). Inicialmente, apenas removi os atributos de largura e altura da imagem depois que ela foi carregada (por meio do evento de carregamento da imagem) e restaurei-os depois de calcular as dimensões preferidas. No entanto, isso não funciona no Safari e, possivelmente, no IE (eu não o testei no IE, mas a imagem nem aparece, então …).

    De qualquer forma, o Safari mantém as dimensões da imagem anterior para que as dimensões fiquem sempre uma imagem atrás. Eu suponho que isso tenha algo a ver com o cache. Portanto, a solução mais simples é apenas clonar a imagem e adicioná-la ao DOM (é importante que ela seja adicionada ao DOM para obter o com e a altura). Dê à imagem um valor de visibilidade oculta (não use display none porque não funcionará). Depois de obter as dimensões, remova o clone.

    Aqui está o meu código usando 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); 

    Esta solução funciona em qualquer caso.

    Existe agora um plugin jQuery, event.special.load , para lidar com casos em que o evento load em uma imagem em cache não é triggersdo: http://github.com/peol/jquery.imgloaded/raw/master/ahpi. imgload.js

    Recentemente, precisei encontrar largura e altura para definir o tamanho padrão do .dialog representando o gráfico. A solução que usei foi:

      graph= $('', {"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 }) }) 

    Para mim isso funciona em FF3, Opera 10, IE 8,7,6

    PS Você pode encontrar mais soluções procurando dentro de alguns plugins como LightBox ou ColorBox

    Para adicionar à resposta de Xavi, o gitgub do github David Desandro do Paul Irish oferece uma function chamada imagesLoaded () que funciona nos mesmos princípios e contorna o problema de algumas imagens em cache do navegador não triggersrem o evento .load () (com original_src -> data_uri -> comutação original_src).

    É amplamente utilizado e atualizado regularmente, o que contribui para que seja a solução mais robusta para o problema, o IMO.

    Isso funciona para imagens carregadas em cache e dinamicamente.

     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."); } } } 

    Para usar este script:

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

    Demonstração: http://jsfiddle.net/9543z/2/

    Eu fiz alguma function de utilitário de contorno, usando o plugin jquery imagesLoaded: 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})); }, 

    Você pode usar isso passando url, function e seu contexto. A function é executada depois que a imagem é carregada e retorna a imagem criada, sua largura e altura.

     waitForImageSize("image.png", function(w,h){alert(w+","+h)},this) 

    Se a imagem já estiver sendo usada, você deve:

    1. definir simulações de imagem para inicial

      image.css (‘width’, ‘initial’); image.css (‘height’, ‘initial’);

    2. obter dimensões

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

    Você pode usar as propriedades naturalWidth e naturalHeight do elemento de imagem HTML. (Aqui está mais informação ).

    Você usaria assim:

     //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; 

    Parece que isso funciona em todos os navegadores, exceto no IE da versão 8 e abaixo.

    Para funções em que você não deseja alterar o posicionamento ou a imagem original.

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

    Eu verifiquei a resposta do Dio e funciona muito bem para mim.

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

    Certifique-se de chamar todas as suas funções. que manipulam o tamanho da imagem na function recaller de fadeIn ().

    Obrigado por isso.

    Eu uso uma abordagem diferente, basta fazer a chamada Ajax para o servidor para obter o tamanho da imagem quando o object de imagem está em uso.

     //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); } } 

    e, claro, código do lado do servidor:

     < ?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); ?> 

    Isso funciona no navegador

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

    obtenha as dimensões usando

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

    Felicidades!

    Outra sugestão é usar o plugin imagesLoaded .

     $("img").imagesLoaded(function(){ alert( $(this).width() ); alert( $(this).height() ); }); 
     $(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); } }); 

    // Este código ajuda a mostrar a imagem com 200 * 274 dimensões

    Aqui está uma solução cross-browser que aciona um evento quando as imagens selecionadas são carregadas: http://desandro.github.io/imagesloaded/ você pode procurar a altura e a largura dentro da function imagesLoaded ().

    Tropeçou nesta discussão tentando encontrar uma resposta para minha própria pergunta. Eu estava tentando obter largura / altura de uma imagem em uma function após o carregador, e continuei chegando com 0. Eu sinto que isso pode ser o que você está procurando, no entanto, como funciona para mim:

     tempObject.image = $('').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); } 

    Confira este repository no github!

    Ótimo exemplo para verificar a largura e a altura usando Javascript

    https://github.com/AzizAK/ImageRealSize

    — Editado é solicitado a partir de alguns comentários ..

    Código 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); } 

    e código HTML:

       Image Real Size