Pergunta

Estou criando um plugin jQuery.

Como posso obter a largura da imagem real e altura com JavaScript no Safari?

a seguir funciona com Firefox 3, IE7 e 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 em navegadores Webkit como valores Safari e Google Chrome são 0.

Foi útil?

Solução

navegadores Webkit definir a altura e largura propriedades após a imagem ser carregada. Em vez de usar o tempo limite, eu recomendo usar evento de carregamento de uma imagem. Aqui está um exemplo rápido:

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

Para evitar qualquer do CSS efeitos pode ter sobre as dimensões da imagem, o código acima faz uma na cópia de memória da imagem. Esta é uma solução muito inteligente sugerido por FDisk .

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

Outras dicas

Use o naturalHeight e atributos naturalWidth de HTML5 .

Por exemplo:

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

Obras em IE9 +, Chrome, Firefox, Safari e Opera ( estatísticas ).


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 estilo a partir da imagem ou dimensões da imagem atributos. Basta criar um elemento com JavaScript e obter a largura objeto criado.

A raiz do problema é que os navegadores WebKit (Safari e Chrome) Carga JavaScript e CSS informações em paralelo. Assim, JavaScript pode executar antes que os efeitos de estilo de CSS foram computados, retornando a resposta errada. Em jQuery, eu descobri que a solução é esperar até document.readyState == 'completa', .e.g.,

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

Quanto largura e altura vai ... dependendo do que você está fazendo, você pode querer offsetWidth e offsetHeight, que incluem coisas como as fronteiras e estofamento.

Há muita discussão na resposta aceita sobre um problema onde o evento onload não dispara se uma imagem é carregada a partir do cache WebKit.

No meu caso, incêndios onload para imagens em cache, mas a altura ea largura ainda são 0. Um simples setTimeout resolvido 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 a respeito de porque o evento onload está a disparar mesmo quando a imagem é carregada a partir do cache (melhoria do jQuery 1.4 / 1.5?) - mas se você ainda estiver enfrentando esse problema, talvez uma combinação de minha resposta ea técnica var src = img.src; img.src = ""; img.src = src; vai funcionar.

(Note-se que para os meus propósitos, eu não estou preocupado com dimensões pré-definidas, seja em atributos da imagem ou estilos CSS -. Mas você pode querer remover aqueles, como por resposta de Xavi ou clonar a imagem.)

Isso funciona para mim (safari 3.2), por aquecimento 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 programaticamente a imagem e verificar as dimensões usando Javascript, sem ter que mexer com o DOM em tudo.

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

E sobre image.naturalHeight e image.naturalWidth propriedades?

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

Como temos reais dimensões certas, sem uma imagem real piscar:

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

Ele funciona com

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

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

Onde meu-img é um nome de classe usado para selecionar a minha imagem.

Como dito antes, Xavi resposta não vai funcionar se as imagens estão no cache. Os responde questão a webkit não disparar o evento de carregamento em imagens em cache, por isso, se a largura / attrs altura não são explicitamente definido no tag img, a única maneira confiável para obter as imagens é esperar para o evento window.load ser demitido.

O evento window.load dispara sempre , por isso é seguro para 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ê precisa para obter o tamanho das imagens carregadas dinamicamente que podem ficar armazenadas em cache (previamente carregados), você pode usar o método Xavi além de uma string de consulta para acionar uma atualização de cache. A desvantagem é que ele fará com que outra solicitação para o servidor, para uma img que já está em cache e deve ser já disponível. Webkit estúpido.

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: se você tem um QueryString no img.src, já que você terá que analisá-lo e adicione o param extra para limpar o cache.

Como Luke Smith diz: carga imagem é uma bagunça . Não é confiável em todos os navegadores. Este fato tem me dado muita dor. A imagem em cache não irá disparar o evento em tudo em alguns navegadores, então aqueles que disseram "load imagem é melhor do que setTimeout" estão errados.

A solução de Luke Smith é aqui.

E há uma discussão interessante sobre como este bagunça pode ser tratado em jQuery 1.4.

Eu descobri que é bastante confiável para definir a largura de 0, e depois esperar para a propriedade "completa" para ir verdadeiro e a largura propriedade para entrar maior que zero. Você deve prestar atenção para erros, também.

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

De comentário Chris': http://api.jquery.com/load-event/

A minha situação é provavelmente um pouco diferente. Eu estou mudando dinamicamente o src de uma imagem via javascript e necessário para garantir que a nova imagem é dimensionada proporcionalmente para caber num recipiente fixo (em uma galeria de fotos). I inicialmente apenas removido a largura e altura atributos da imagem, depois de carregado (via evento de carregamento da imagem) e repor estes depois de calcular as dimensões preferidas. No entanto, isso não funciona no Safari e, possivelmente, IE (eu não testei no IE completamente, mas a imagem não mostram mesmo, então ...).

De qualquer forma, Safari mantém as dimensões da imagem anterior para as dimensões são sempre uma imagem para trás. Presumo que isso tem algo a ver com o cache. Portanto, a solução mais simples é clone da imagem e adicioná-lo ao DOM (é importante que ele seja adicionado ao DOM a obter o com e altura). Dar a imagem um valor visibilidade do oculto (não use nenhum exibição porque não vai funcionar). Depois de obter as dimensões remover 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 onde o evento de carga em uma imagem em cache não dispara: http://github.com/peol/jquery.imgloaded/raw/master/ahpi.imgload.js

Recentemente eu precisava encontrar largura e altura para definir o tamanho padrão de .dialog gráfico que representa. Solução que eu uso foi:

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

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

P.S. Você pode ser encontrar mais algumas soluções que olha dentro de alguns plugins como LightBox ou ColorBox

de

Para adicionar a resposta de Xavi, Paul Irish github David Desandro gitgub oferece uma função de chamada imagesLoaded () que as obras nos mesmos princípios, e fica em torno do problema de imagens em cache de algum navegador não disparar o evento .load () (com original_src inteligente -> data_uri -> original_src de comutação).

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

Isso funciona para ambas as imagens em cache e carregados 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/

Já fiz alguns função de utilidade solução alternativa, usando imagesLoaded jquery plugin: 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, função e seu contexto. A função é realizada após a imagem é carregado e retornar imagem criada, a sua largura e altura.

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

Se a imagem já é usado, você sholud:

  1. imagem Jogo simensions a inicial

    image.css ( 'largura', 'primeiro'); image.css ( 'altura', 'inicial');

  2. get 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ções ).

Você poderia usá-lo como este:

//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 a partir da versão 8 e abaixo.

Para funções onde você não deseja alterar a localização original ou imagem.

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

Eu confirmei a resposta de Dio e ele funciona muito bem para mim.

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

Certifique-se de que você chamar todas as suas funções aso. que pega com o tamanho da imagem na função Confirmador de fadeIn ().

Obrigado por isso.

Eu uso abordagem diferente, basta fazer a chamada Ajax ao servidor para obter o tamanho da imagem quando objeto 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, o 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 cross browser

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

obter as dimensões usando

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

Felicidades!

Outra sugestão é usar imagesLoaded plug-in .

$("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 imagem com 200 * 274 dimention

Aqui está uma solução cross browser que desencadeia um evento quando suas imagens selecionadas são carregados: http: //desandro.github .io / imagesloaded / você pode olhar para cima a altura ea largura dentro da função imagesLoaded ().

Tropeçamos a esta discussão tentando encontrar uma resposta para a minha pergunta. Eu estava tentando obter a largura de uma imagem / altura em uma função após o carregador, e manteve chegando com 0. Eu sinto que isso pode ser o que você está procurando, embora, como ele funciona para mim:

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

Confira este repositório no github!

grande exemplo para verificar a largura e altura usando Javascript

https://github.com/AzizAK/ImageRealSize

--- Editado é solicitado 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:

<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>
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top