用JavaScript获取图像的实际宽度和高度?(在Safari和Chrome)

我正在创建一个jQuery插件。

我如何得到真实的图像宽度和高度与Javascript在Safari?

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和谷歌等Webkit浏览器中,Chrome的值为0。

399479 次浏览

这适用于我(safari 3.2),通过从window.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中,我发现解决方案是等到文档。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.
});

为了避免CSS对图像尺寸的影响,上面的代码在内存中复制了图像。这是FDisk提出的一个非常聪明的解决方案。

你也可以使用naturalHeightnaturalWidth HTML5属性。

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

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

正如卢克·史密斯所说,图像加载是一团糟。它在所有浏览器上都不可靠。这个事实给了我极大的痛苦。缓存的图像在某些浏览器中根本不会触发事件,所以那些说“图像加载比setTimeout更好”的人是错误的。

Luke Smith的解决方案是在这里。

并且有一个有趣的讨论关于如何在jQuery 1.4中处理这个混乱。

我发现这是相当可靠的设置宽度为0,然后等待“完成”属性为真,宽度属性来大于零。您还应该注意错误。

以前< p > < > <代码> 函数getOriginalWidthOfImg(img_element) { var t = new Image(); T.src = (img_element。getAttribute吗?img_element.getAttribute("src"): false) || 返回t.width; } < / pre > < /代码> < / p >

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

$("#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/

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

我们如何在不眨眼的情况下获得正确的真实尺寸:

(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"…

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

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

确保你调用了所有的函数。在fadeIn()的召回函数中处理图像大小。

谢谢你。

我使用不同的方法,简单地使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);


?>

最近我需要找到宽度和高度设置默认大小的.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这样的插件中找到更多的解决方案

如果从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的回答,您可能想要删除这些维度。或者克隆图像。)

使用HTML5中的naturalHeightnaturalWidth属性。

例如:

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

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

为了补充Xavi的答案,Paul Irish的github . David Desandro的gitgub提供了一个名为imagesLoaded()的函数的工作原理相同,并解决了一些浏览器的缓存图像不触发.load()事件的问题(与聪明的original_src -> data_uri -> original_src切换)。

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

如前所述,如果图像在缓存中,哈维的答案将不起作用。这个问题响应webkit没有对缓存的图像触发加载事件,所以如果宽度/高度attrs没有在img标签中显式设置,唯一可靠的获取图像的方法是等待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,你必须解析它并添加额外的参数来清除缓存。

另一个建议是使用imagesLoaded插件

$("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;

干杯!

image.naturalHeightimage.naturalWidth属性是什么?

在Chrome、Safari和Firefox的一些版本中似乎都运行得很好,但在IE8甚至IE9中就完全不行。

这对缓存的和动态加载的图像都有效。

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/

我已经做了一些变通的实用函数,使用imagesLoaded jquery插件: https://github.com/desandro/imagesloaded < / p >
            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)

您可以通过编程方式获取图像,并使用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';
$(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维度的图像

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

Safari保留了前一张图片的尺寸所以尺寸总是在后面一张图片上。我认为这和缓存有关。因此,最简单的解决方案是克隆图像并将其添加到DOM中(重要的是将其添加到DOM中以获得with和height)。给图像一个可见值为hidden(不要使用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);

这个解决方案在任何情况下都有效。

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

无意中发现了这条线索,试图为我自己的问题找到答案。我试图在加载程序后的函数中获得图像的宽度/高度,并不断得到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);
}

如果图像已经被使用,你应该:

  1. 设置图像尺寸为初始值

    < p > image.css(“宽度”,“初始”); image.css(“高度”,“初始”);< / p > < /李>
  2. < p >维度

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

  3. . var

Jquery有两个属性叫做naturalWidth和naturalHeight,你可以这样使用。

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

其中my-img是一个类名,用于选择我的图像。

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

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

你可以这样使用它:

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

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