首页 文章

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

提问于
浏览
267

我正在创建一个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

    使用HTML5中的 naturalHeightnaturalWidth 属性 .

    例如:

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

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

  • 1

    我查看了Dio的答案,它对我很有用 .

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

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

    谢谢你 .

  • 1

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

    Luke Smith的解决方案是here.

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

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

  • 1

    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属性 .

  • 348

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

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

    它适用于<img class =“toreaddimensions”......

  • 3

    我的情况可能有点不同 . 我通过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);
    

    该解决方案无论如何都适用 .

  • 1

    偶然发现这个线程试图找到我自己的问题的答案 . 我试图在加载器之后的函数中获得图像的宽度/高度,并且不断提出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);
    }
    
  • 275

    另一个建议是使用imagesLoaded plugin .

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

    这适用于我(safari 3.2),通过在 window.onload 事件中触发:

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

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

  • 58

    最近我需要找到宽度和高度来设置表示图形的.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

    附:您可能会在LightBox或ColorBox等插件中找到更多解决方案

  • 2

    如果图像已经使用过,那么你就会嗤之以鼻:

    • 将图像simensions设置为初始值

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

    • 获取尺寸

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

  • 0

    我已经使用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)
    
  • 5

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

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

    您可以使用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
    $(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维度的图像

  • 11

    image.naturalHeightimage.naturalWidth 属性怎么样?

    似乎工作得很好Chrome,Safari和Firefox中的版本,但在IE8甚至IE9中都没有 .

  • 4

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

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

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

  • 5

    为了增加Xavi的答案,Paul Irish的github David Desandro's gitgub offers a function called imagesLoaded()以相同的原则工作,并解决了一些浏览器缓存图像的问题,没有触发.load()事件(使用聪明的original_src - > data_uri - > original_src切换) .

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

  • 1

    这适用于跨浏览器

    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;
    

    干杯!

  • 0

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

  • 0

    在接受的答案中有很多关于如果从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);
    });
    

    我不能说为什么 onload 事件即使从缓存加载图像时也会被触发(jQuery 1.4 / 1.5的改进?) - 但如果你仍然遇到这个问题,可能是我的答案和 var src = img.src; img.src = ""; img.src = src; 的组合技术会起作用 .

    (请注意,就我的目的而言,我并不关心图像属性或CSS样式中的预定义尺寸 - 但您可能希望根据Xavi的答案删除它们 . 或者克隆图像 . )

  • 0
    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创建一个元素并获取创建的对象宽度 .

  • 0

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

    window.load 事件将触发 always ,因此在没有任何技巧的情况下访问宽度/高度和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并添加额外的参数以清除缓存 .

  • 1

    在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>
    
  • 2

    根本问题是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,其中包括边框和填充等内容 .

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

  • 0

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

    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/

  • 1

    您可以使用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';
    

相关问题