使用JavaScript获取图像的真实宽度和高度? (在Safari / Chrome中)

时间:2008-11-25 19:44:39

标签: javascript jquery safari google-chrome webkit

我正在创建一个jQuery插件。

如何在Safari中使用Javascript获得真实的图像宽度和高度?

以下适用于Firefox 3,IE7和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();

但在像Safari和Google Chrome这样的Webkit浏览器中,值为0。

30 个答案:

答案 0 :(得分:350)

Webkit浏览器在加载图像后设置height和width属性。我建议使用图像的onload事件,而不是使用超时。这是一个简单的例子:

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

为避免CSS可能对图像的尺寸产生任何影响,上面的代码会生成图像的内存副本。这是FDisk建议的一个非常聪明的解决方案。

您还可以使用naturalHeightnaturalWidth HTML5属性。

答案 1 :(得分:279)

使用HTML5中的naturalHeightnaturalWidth属性。

例如:

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

适用于IE9 +,Chrome,Firefox,Safari和Opera(stats)。

答案 2 :(得分:59)


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

您无需从图像或图像尺寸属性中删除样式。只需使用javascript创建一个元素并获取创建的对象宽度。

答案 3 :(得分:16)

根本问题是WebKit浏览器(Safari和Chrome)并行加载JavaScript和CSS信息。因此,JavaScript可以在计算CSS的样式效果之前执行,返回错误的答案。在jQuery中,我发现解决方案是等到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) 

就宽度和高度而言......取决于你正在做什么,你可能需要offsetWidth和offsetHeight,其中包括边框和填充等内容。

答案 4 :(得分:16)

在接受的答案中有很多关于如果从WebKit缓存加载图像时onload事件不会触发的问题的讨论。

在我的情况下,onload会触发缓存图片,但高度和宽度仍为0.简单的setTimeout解决了我的问题:

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

即使从缓存中加载图像(jQuery 1.4 / 1.5的改进?),我也无法解释为什么onload事件正在触发 - 但如果你仍然遇到这个问题,也许是我的答案和var src = img.src; img.src = ""; img.src = src;技术的组合将起作用。

(请注意,就我的目的而言,我并不关心预定义的尺寸,无论是在图像的属性还是CSS样式中 - 但您可能想要删除它们,根据Xavi的答案。或者克隆图像。)< / p>

答案 5 :(得分:11)

这适用于我(safari 3.2),在window.onload事件中开火:

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

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

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

答案 6 :(得分:8)

您可以使用Javascript以编程方式获取图像并检查尺寸,而无需根据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';

答案 7 :(得分:6)

image.naturalHeightimage.naturalWidth属性呢?

似乎可以在Chrome,Safari和Firefox中使用相当多的版本,但在IE8甚至IE9中都没有。

答案 8 :(得分:5)

我们如何在没有闪烁真实图像的情况下获得正确的尺寸:

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

适用于&lt; img class =“toreaddimensions”......

答案 9 :(得分:4)

Jquery有两个名为naturalWidth和naturalHeight的属性,你可以这样使用。

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

my-img是用于选择我的图像的类名。

答案 10 :(得分:3)

如前所述,如果图像在缓存中,Xavi answer将无效。该问题响应webkit没有在缓存的图像上触发加载事件,因此如果未在img标记中显式设置宽度/高度attrs,获取图像的唯一可靠方法是等待window.load事件被解雇了。

window.load事件将触发始终,因此可以安全地访问其后的宽度/高度,并且无需任何技巧即可进行img。

$(window).load(function(){

   //these all work

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

});

如果您需要获取可能被缓存(先前加载)的动态加载图像的大小,您可以使用Xavi方法加上查询字符串来触发缓存刷新。缺点是它将导致另一个请求到服务器,对于已经缓存并且应该已经可用的img。愚蠢的Webkit。

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:如果您已经在img.src中拥有QueryString,则必须parse it并添加额外的参数以清除缓存。

答案 11 :(得分:2)

我的情况可能有点不同。我通过javascript动态更改图像的src,并且需要确保新图像的大小按比例调整以适合固定容器(在照片库中)。我最初只是在加载图像后(通过图像的加载事件)删除了图像的宽度和高度属性,并在计算首选尺寸后重置这些属性。但是,这在Safari和IE中都不起作用(我没有在IE中彻底测试它,但图像甚至没有显示,所以......)。

无论如何,Safari保留了上一个图像的尺寸,因此尺寸始终是一个图像。我认为这与缓存有关。所以最简单的解决方案就是克隆图像并将其添加到DOM(重要的是将它添加到DOM中获取with和height)。为图像提供隐藏的可见性值(不要使用display none,因为它不起作用)。获得维度后删除克隆。

这是我使用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);

此解决方案无论如何都适用。

答案 12 :(得分:2)

正如卢克史密斯所说,image load is a mess。它在所有浏览器上都不可靠。这个事实给了我很大的痛苦。在某些浏览器中,缓存的图像根本不会触发事件,因此那些说“图像加载比setTimeout好”的人是错误的。

Luke Smith的解决方案是here.

关于如何在jQuery 1.4中处理这个混乱,有an interesting discussion

我发现将宽度设置为0非常可靠,然后等待“complete”属性为true,width属性大于零。你也应该注意错误。

答案 13 :(得分:2)

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

来自Chris的评论:http://api.jquery.com/load-event/

答案 14 :(得分:1)

我使用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}));
            },

您可以通过传递url,函数及其上下文来使用它。加载图像并返回创建的图像,宽度和高度后执行功能。

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

答案 15 :(得分:1)

您可以使用HTML图像元素的naturalWidth和naturalHeight属性。 (这里有更多info)。

您可以这样使用它:

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

似乎这适用于所有浏览器,除了在版本8及以下的IE上。

答案 16 :(得分:1)

如果图像已经使用过,那么你应该喋喋不休:

  1. 将图像simensions设置为初始

    image.css('width','initial'); image.css('height','initial');

  2. 获取尺寸

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

答案 17 :(得分:1)

最近我需要找到宽度和高度来设置代表图形的.dialog的默认大小。我使用的解决方案是:

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

对我而言,这适用于FF3,Opera 10,IE 8,7,6

P.S。您可能会在LightBox或ColorBox

等插件中找到更多解决方案

答案 18 :(得分:1)

这适用于缓存和动态加载的图像。

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

要使用此脚本:

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

演示:http://jsfiddle.net/9543z/2/

答案 19 :(得分:1)

现在有一个jQuery插件event.special.load,用于处理缓存图像上的加载事件无法触发的情况:http://github.com/peol/jquery.imgloaded/raw/master/ahpi.imgload.js

答案 20 :(得分:1)

要添加到Xavi的答案, Paul Irish's github David Desandro's gitgub offers a function called imagesLoaded()符合相同的原则,并解决一些浏览器缓存图像的问题,而不是触发.load()事件(聪明的original_src - &gt; data_uri - &gt; original_src切换)。

它被广泛使用和定期更新,这有助于它成为解决问题的最有力的解决方案,IMO。

答案 21 :(得分:0)

这适用于跨浏览器

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

使用

获取尺寸
$(this).data('dimensions').width;
$(this).data('dimensions').height;

干杯!

答案 22 :(得分:0)

另一个建议是使用imagesLoaded plugin

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

答案 23 :(得分:0)

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

//此代码有助于显示200 * 274维度的图像

答案 24 :(得分:0)

这是一个跨浏览器解决方案,可以在加载所选图像时触发事件:http://desandro.github.io/imagesloaded/您可以在imagesLoaded()函数中查找高度和宽度。

答案 25 :(得分:0)

偶然发现这个帖子试图找到我自己问题的答案。我试图在加载器之后的函数中获得图像的宽度/高度,并且不断提出0.我觉得这可能是你正在寻找的东西,因为它适用于我:

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

答案 26 :(得分:0)

我检查了Dio的答案,它对我很有用。

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

确保您调用所有功能。在fadeIn()的recaller函数中处理图像大小。

谢谢你。

答案 27 :(得分:0)

适用于您不想改变原始位置或图像的功能。

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

答案 28 :(得分:0)

在github中查看此存储库!

使用Javascript检查宽度和高度的好例子

https://github.com/AzizAK/ImageRealSize

---从一些评论中要求编辑..

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

和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>

答案 29 :(得分:0)

我使用不同的方法,只需对服务器进行Ajax调用,以便在使用图像对象时获取图像大小。

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

当然还有服务器端代码:

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

?>