ChatGPT解决这个技术问题 Extra ChatGPT

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

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

接受的答案使用图像加载事件。完全有道理,但在可以缓存图像的情况下(令我沮丧),结果证明这是一个不可靠的解决方案。
我对此的看法可能会对您有所帮助,并在最新的 Webkit 中进行了测试。 stackoverflow.com/questions/318630/…
@Nosredna,您可能对即使在缓存图像时也会触发的 imagesLoaded 函数感兴趣。
这个问题的正确答案是简单地使用 naturalWidth 和 naturalHeight 属性。无需骇客。
您也可以在窗口加载时执行您正在执行的操作,而不是准备好文档

C
Community

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


这很聪明,不知道你可以这样做 $(img).load();
除了 widthheight,您可能还应该删除 min-widthmin-heightmax-widthmax-height,因为它们也会影响图像尺寸。
FDisk 的解决方案非常巧妙。不幸的是,他所写的解决方案只有在图像被缓存或页面已经完成下载时才有效。如果图像未缓存或者如果在 window.onload 之前调用此代码,则可能会返回 0 的高度/宽度。无论如何,我已经将 FDisk 的想法整合到了上面的解决方案中。
当我尝试 console.log(pic_real_height) 时,我每次都不确定。铬,FF,IE9。
您可能遇到的问题是 load() 将异步执行,因此如果您想访问 widthheight — 它们可能尚未设置。而是在 load() 本身中做“魔术”!
s
sandstrom

使用 HTML5 中的 naturalHeightnaturalWidth 属性。

例如:

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

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


@DavidJohnstone 使用它们的一个例子可能会有所帮助。但我同意,绝对值得更高。
除非图像已存在于缓存中,否则这似乎不适用于最新版本的 FireFox (30.0)。
我同意大卫约翰斯通的观点。这是个好消息。
请注意,您仍然需要等待图像加载
不,clientHeight/clientWidth 明确不做问题所要求的。它需要返回图像的高度和宽度,而不是图像在页面上显示的高度和宽度。 naturalWidth 和 naturalHeight 是正确的。
F
FDisk


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


几个月以来,使用 jquery 克隆图像(使用最新的 Chrome)并获取它的属性,始终返回 0x0 到目前为止,这是唯一有效的解决方案(已测试此页面中的所有其他解决方案)在返回之前,我设置 t=也为空。
FDisk 不建议使用 jQuery 克隆图像。他建议创建一个新的 Image 对象,然后查看它的 width 属性。这是一种简单、优雅的方法。 FDisk,你有我的投票权。 :)
这是避免 css 问题的一种非常聪明的方法。不幸的是,上面写的解决方案只有在图像被缓存或已经完成下载时才有效。如果图像未缓存或者如果在 window.onload 之前调用此代码,则可能会返回 0 的宽度。
我在图片库中的手机网站中使用了这种方法。更大的图像然后分辨率以 100% 的 css 和更小的原始尺寸显示。
正如 Xavi 提到的,这在 IE8 中失败,有时取决于图像缓存。所以我把它和这个方法结合起来,效果很好:先绑定加载事件,然后将图像对象分配给它的源stackoverflow.com/questions/4921712/…
J
JKS

在接受的答案中有很多关于如果从 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 的回答删除这些尺寸。或者克隆图像。)


我在 IE7 和 IE8 上遇到了这个问题。 setTimeout() 为我工作的那些浏览器。谢谢!
C
Cugel

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

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

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


是的,就是这个原因。更好的解决方法是使用 jQuery 的加载事件。
$(window).load(function(){ ... }); 对我有帮助
O
Owen

通过从 window.onload 事件中触发,这对我有用(safari 3.2):

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

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

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

是的!不能从 $(document).ready(function(){});谢谢!它需要在读取图像之前完全加载图像。当然。
Y
Yëco

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

这是最好的解决方案!即使图像未预加载或缓存,它也可以工作。
a
alex

image.naturalHeightimage.naturalWidth 属性呢?

似乎在 Chrome、Safari 和 Firefox 中的很多版本都可以正常工作,但在 IE8 甚至 IE9 中根本不行。


这在我的情况下不起作用。给我 NaN 作为回报
S
Samuel Santos

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

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

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


这些不是 jQuery 方法。 naturalWidth(和高度)是图像元素对象的属性。 developer.mozilla.org/en/docs/Web/API/HTMLImageElement
F
Fox

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

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

它适用于


C
Community

如前所述,如果图像在缓存中,Xavi answer 将不起作用。该问题响应 webkit 未触发缓存图像的加载事件,因此如果未在 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,您将必须 parse it 并添加额外的参数以清除缓存。


第一个代码块只是获取加载的 DOM 中元素的尺寸,而不是图像本身的尺寸......
这正是最快和最有效的解决方案。没有插件,没有技巧!我将发布一个类似的答案,但找到了你的答案。
N
Nosredna

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

Luke Smith 的解决方案是 here.

还有 an interesting discussion 关于如何在 jQuery 1.4 中处理这种混乱。

我发现将宽度设置为 0 非常可靠,然后等待“完成”属性变为真并且宽度属性大于零。你也应该注意错误。


答案中的第二个链接已失效。
J
Jerome Jaglale
$("#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/


D
Duane Comeaux

我的情况可能有点不同。我正在通过 javascript 动态更改图像的 src,并且需要确保新图像的大小按比例调整以适合固定容器(在照片库中)。我最初只是在加载图像后(通过图像的加载事件)删除了图像的宽度和高度属性,并在计算了首选尺寸后重置了这些属性。但是,这在 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);

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


S
S P

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


S
SDemonUA

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

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


R
RobW

要添加到 Xavi 的答案, Paul Irish's github David Desandro's gitgub offers a function called imagesLoaded() 工作原理相同,并解决了某些浏览器的缓存图像未触发 .load() 事件的问题(使用聪明的 original_src -> ; data_uri -> original_src 切换)。

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


您可以在此处找到 imagesLoaded 函数的更新版本:github.com/desandro/imagesloaded
是的,David Desandro 现在正在主持这个活动。感谢您提醒我@somethingkindawierd,更新了我的答案。
C
CheeseSucker

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

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/


Z
Zdeněk Mlčoch

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

S
Sebastián Rojas

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

将图像尺寸设置为初始 image.css('width', 'initial'); image.css('高度', '初始');获取尺寸 var originalWidth = $(this).width(); var originalHeight = $(this).height();


J
Jair Reina

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

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


是的,没有更多的 IE8 :D
d
drublic

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

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

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

谢谢你。


d
damijanc

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

?>

这不是一个很好的解决方案,并且由于 AJAX 加载,它需要比任何其他解决方案更长的时间。
f
foxybagga

这适用于跨浏览器

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;

干杯!


B
Bobby

另一个建议是使用 imagesLoaded plugin

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

E
Eranda
$(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 尺寸的图像


P
Paul Mason

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


S
Stephen Synowsky

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

A
Abdulaziz Alkharashi

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

如果可能的话,您还可以在此处添加几行代码。因为链接可能会随着时间而改变
D
Davin

对于您不想更改原始位置或图像的功能。

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

这绝对行不通。它将为两者返回 undefined