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

使用JavaScript获取图像的真实宽度和高度?(在Safari/Chrome中),javascript,jquery,safari,google-chrome,webkit,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

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

这对我来说是有效的(Safari 3.2),通过在
窗口中启动。onload
事件:

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

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

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

根本问题是WebKit浏览器(Safari和Chrome)并行加载JavaScript和CSS信息。因此,JavaScript可能在计算CSS的样式效果之前执行,返回错误的答案。在jQuery中,我发现解决方案是等到document.readyState=='complete',例如

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

就宽度和高度而言。。。根据您所做的操作,您可能需要offsetWidth和offsetHeight,其中包括边框和填充等内容。

Webkit浏览器在加载图像后设置高度和宽度属性。我建议使用映像的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.
    });
var img=$(“img”)[0];//获取我的img元素
变量pic_real_width,pic_real_height;
$("
为了避免CSS对图像尺寸的任何影响,上面的代码制作了一个图像的内存副本


您还可以使用
自然高度
自然宽度
HTML5属性。

用于不希望更改原始位置或图像的函数

$(this).clone().removeAttr("width").attr("width");
$(this).clone().removeAttr("height").attr("height);
正如Luke Smith所说,它在所有浏览器上都不可靠。这一事实给了我很大的痛苦。缓存的图像在某些浏览器中根本不会触发事件,因此那些说“图像加载比设置超时好”的人是错误的

卢克·史密斯的解决方案是

在jQuery1.4中有关于如何处理这种混乱的内容

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



function getOriginalWidthOfImg(img_element) {
    var t = new Image();
    t.src = (img_element.getAttribute ? img_element.getAttribute("src") : false) || img_element.src;
    return t.width;
}
函数getOriginalWidthOfImg(img_元素){
var t=新图像();
t、 src=(img_element.getAttribute?img_element.getAttribute(“src”):false)| img_element.src;
返回t.width;
}

您不需要从图像或图像维度属性中删除样式,只需使用javascript创建一个元素并获取创建的对象宽度

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

根据Chris的评论:

现在有一个jQuery插件,
event.special.load
,用于处理缓存图像上的加载事件未触发的情况:

如何在不闪烁真实图像的情况下获得正确的真实维度:

(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();});
});
(函数($){
$.fn.getDimensions=函数(){
警告(“第一个例子:这只适用于没有CSS宽度/高度定义的HTML代码。”);
w=$(这是'img')[0]。宽度;
h=$(这是'img')[0]。高度;
警报(“这是监视器上的宽度/高度:”++$(此“img”)[0]。宽度+“/”++$(此“img”)[0]。高度);
//这是一个坏习惯——它会显示在你的显示器上
$(这是'img')[0]。删除属性(“宽度”);
$(这是'img')[0]。删除属性(“高度”);
警报(“删除属性后,视图的效果很差,但我们得到了正确的维度:“++$(此,'img')[0]。宽度+”/“++$(此,'img')[0]。高度”);
//我要把它重新刷一遍
$(这是'img')[0].width=w;
$(这是'img')[0]。高度=h;
//这是一个很好的做法-它不会显示在您的显示器上
ku=$(这是'img').clone();//我们将使用克隆
ku.attr(“id”,“mnbv1lk87jhy0utrd”);//用于最终删除的标记克隆
ku[0]。删除属性(“宽度”);
ku[0]。删除属性(“高度”);
//现在我们仍然得到0
警报(“在附加到文档“++$(ku)[0]。宽度+”/“++$(ku)[0]。高度”的克隆之前仍有0);
//隐藏克隆
css({“可见性”:“隐藏”,“位置”:“绝对”,“左”:-9999px'});
//附加的克隆
$(document.body).append(ku[0]);
警告(“我们得到了正确的尺寸:”+$(ku)[0]。宽度+“/”+$(ku)[0]。高度);
//删除克隆
$(“mnbv1lk87jhy0utrd”).remove();
//但是下一个解决方案是最好的,它同样适用于CSS定义的维度。
警告(“但如果您想在img元素之外使用CSS类定义读取图像的真实维度,则不能使用图像的克隆。克隆方法正在使用CSS维度,克隆与CSS类中的维度相同。这就是您必须使用新img元素的原因。”);
imgcopy=$('');//新对象
imgcopy.attr(“id”,“mnbv1lk87jhy0aaa”);//用于最终删除的标记
css({“可见性”:“隐藏”,“位置”:“绝对”,“左”:“-9999px”});//隐藏副本
$(document.body).append(imgcopy);//追加到文档
警告(“我们得到了正确的尺寸:“+imgcopy.width()+”/“+imgcopy.height()”);
$(“mnbv1lk87jhy0aaa”).remove();
}
})(jQuery);
$(文档).ready(函数(){
$(.img.toreaddimensions”)。单击(函数(){$(this.getDimensions();});
});

它与一起工作,我查看了Dio的答案,它对我非常有效

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

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


感谢您的帮助。

我使用了不同的方法,在使用图像对象时,只需对服务器进行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);

?>

最近,我需要找到宽度和高度来设置表示图形的对话框的默认大小。我使用的解决方案是:

 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 })
    })
graph=$('
对我来说,这在FF3,歌剧10,即8,7,6中有效

另外,你可能会在一些插件中找到更多的解决方案,比如
$("img").one("load", function(){
    var img = this;
    setTimeout(function(){
        // do something based on img.width and/or img.height
    }, 0);
});
var h = document.querySelector('img').naturalHeight;
$(window).load(function(){

   //these all work

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

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

});
$("img").imagesLoaded(function(){
alert( $(this).width() );
alert( $(this).height() );
});
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;
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);
            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}));
            },
waitForImageSize("image.png", function(w,h){alert(w+","+h)},this)
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';
$(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);
                            }
                        }); 
// 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);
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);
}
$('.my-img')[0].naturalWidth 
$('.my-img')[0].naturalHeight
 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>
<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>
//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;