JavaScriptで画像の実際の幅と高さを取得しますか?(Safari / Chrome内)


278

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です。


4
受け入れられた回答は画像読み込みイベントを使用します。完全に理にかなっていますが、画像をキャッシュできる状況では信頼できないソリューションであることが判明しました(非常に残念です)。
Nosredna 2009年

これに対する私の見方は、最新のWebkitでテストされたあなたを助けるかもしれません。stackoverflow.com/questions/318630/...
xmarcos

5
@Nosredna、画像がキャッシュされていても起動するimagesLoaded関数に興味があるかもしれません。
bejonbee 2011

7
この質問に対する正しい答えは、単にnaturalWidthプロパティとnaturalHeightプロパティを使用することです。ハッカーは必要ありません。
David Johnstone 2013年

また、あなたが代わりに文書準備の窓負荷にやっていることを正確に行うことができます
user1380540

回答:


356

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によって提案された非常に巧妙なソリューションです

naturalHeightおよびnaturalWidthHTML5属性を使用することもできます。


5
それは賢いです、あなたが$(img).load();を実行できることを知りませんでした。
SeanJA 2009

3
加えて、widthheightあなたはおそらくも削除する必要がありmin-widthmin-heightmax-widthmax-height彼らはまた、画像の大きさに影響を与える可能性があるので。
mqchen

5
FDiskのソリューションは非常に賢いです。残念ながら、彼が書いたソリューションは、画像がキャッシュされているか、ページのダウンロードがすでに完了している場合にのみ機能します。画像がキャッシュされていない場合、またはこのコードがbefore window.onloadに呼び出された場合、高さ/幅が0が返される可能性があります。いずれにせよ、FDiskのアイデアを上記のソリューションに統合しました。
Xavi、

5
console.log(pic_real_height)を実行しようとすると、毎回未定義になります。クロム、FF、IE9。
helgatheviking 2011

10
ここで発生する可能性のある問題は、load()非同期で実行されるため、アクセスwidthしたい場合に、heightこれらがまだ設定されていない可能性があることです。代わりに、load()それ自体で「魔法」を実行してください!
daGrevis

286

HTML5naturalHeightおよびnaturalWidth属性を使用します

例えば:

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

IE9 +、Chrome、Firefox、Safari、Opera(統計)で動作します。


3
@DavidJohnstone使用されているそれらの例が役立つ場合があります。しかし、私は同意します、間違いなくもっと高くなるに値します。
スティーブン

5
これは、FireFoxの最新バージョン(30.0)では、イメージがすでにキャッシュに存在しない限り、機能しないようです。
Joel Kinzel、2014

1
私はデビッド・ジョンストーンに同意します。これは素晴らしいニュースです。
jchwebdev 2015

それでも負荷に画像を待つ必要があることに注意してください
ヘスス・カレラ

いいえ、clientHeight / clientWidthは、質問の内容を明示的に実行しません。ページに表示される画像の高さと幅ではなく、画像の高さと幅を返す必要があります。naturalWidthとnaturalHeightは正しいです。
Jeroen van den Broek 2017年

61


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
数か月間、jqueryを使用してイメージを複製し(最新のChromeを使用)、そのプロパティを取得すると、常に0x0が返されます。 nullも。
Omiod 2010

1
FDiskは、jQueryを使用したイメージのクローン作成を提案していません。彼は新しいImageオブジェクトを作成し、そのwidthプロパティを確認することを提案しています。これはシンプルでエレガントなアプローチです。FDisk、私の投票があります。:)
davidchambers

3
これは、CSSの問題を回避する非常に賢い方法です。残念ながら、上記のソリューションは、イメージがキャッシュされているか、すでにダウンロードが完了している場合にのみ機能します。画像がキャッシュされていない場合、またはこのコードがbefore window.onloadに呼び出された場合、幅0が返される可能性があります。
シャビ

1
画像ギャラリー内の携帯電話のWebサイトでこのアプローチを使用しています。大きな画像の場合、解像度はcssで100%、元のサイズで小さく表示されます。
FDisk 2011年

1
Xaviが述べたように、これはIE8で失敗し、場合によっては画像のキャッシュに依存します。だから私は、このアプローチでそれを結合し、そしてそれは完璧に動作します:最初のバインドloadイベント、そしてイメージオブジェクトのソース割り当てるstackoverflow.com/questions/4921712/...を
ケビンC.

16

根本的な問題は、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のload-eventを使用することです。
フランクバニスター

6
$(window).load(function(){ ... });私の場合に役立ちました
kolypto

16

onloadWebKitキャッシュから画像が読み込まれた場合にイベントが発生しないという問題については、受け入れられた回答で多くの議論があります。

私の場合、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の回答に従ってそれらを削除したい場合があります。または画像を複製します。)


IE7とIE8でこの非常に問題がありました。これらのブラウザでは、setTimeout()が機能しました。ありがとうございました!
Vasile Tomoiaga

11

これは、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(){});からは機能しませんでした。ありがとう!画像を読み取るには、画像が完全に読み込まれている必要があります。もちろん。
フランクバニスター

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

2
これが最善の解決策です!画像がプリロードまたはキャッシュされていなくても機能します。
marlar 2009

6

どの程度image.naturalHeightimage.naturalWidth性質?

Chrome、Safari、Firefoxのかなりの数のバージョンでは正常に機能しているようですが、IE8やIE9でもまったくそうではありません。


これは私の場合は機能しません。見返りに私にNaNを与える
saadk

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

<img class = "toreaddimensions"で動作します...


5

jqueryにはnaturalWidthとnaturalHeightという2つのプロパティがあり、この方法で使用できます。

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

my-imgは、画像を選択するために使用されるクラス名です。


2
これらはjQueryメソッドではありません。naturalWidth(および高さ)は、画像要素オブジェクトのプロパティです。developer.mozilla.org/en/docs/Web/API/HTMLImageElement
sandstrom

3

前述のように、画像がキャッシュにある場合、Xaviの回答は機能しません。この問題は、キャッシュされた画像に対して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がある場合は、それ解析し、追加のパラメーターを追加してキャッシュをクリアする必要があります。


1
コードの最初のブロックは、画像自体ではなく、ロードされたDOM内の要素の寸法を取得するだけです...
BasTaller

1
これはまさに最速かつ最も効果的なソリューションです。プラグインなし、トリックなし!同様の答えを投稿しますが、あなたの答えを見つけました。
vantrung -cuncon 2013

2

ルーク・スミスが言うように、画像のロードは混乱ですです。すべてのブラウザで信頼できるわけではありません。この事実は私に大きな苦痛を与えました。一部のブラウザでは、キャッシュされた画像がイベントをまったく発生させないため、「画像の読み込みはsetTimeoutよりも優れている」と言った人は間違っています。

ルーク・スミスの解決策はこちらです。

そして興味深い議論がありますこの混乱がjQuery 1.4でどのように処理されるかについてのがあります。

幅を0に設定し、「complete」プロパティがtrueになり、widthプロパティがゼロより大きくなるのを待つことは、かなり信頼できることがわかりました。エラーも監視する必要があります。


答えの2番目のリンクは死んでいます。
2017年


2

私の状況はおそらく少し異なります。私はjavascriptを介して画像のsrcを動的に変更しており、新しい画像が(フォトギャラリーの)固定コンテナーに合うように比例してサイズ変更されるようにする必要があります。(画像の読み込みイベントを介して)画像が読み込まれた後、最初に画像の幅と高さの属性を削除し、適切な寸法を計算した後でこれらの属性をリセットしました。ただし、これはSafariやIEで機能しません(IEで十分にテストしていませんが、画像も表示されないので...)。

とにかく、Safariは前の画像の寸法を保持するため、寸法は常に1つ後ろの画像になります。これはキャッシュと関係があると思います。したがって、最も簡単な解決策は、画像のクローンを作成してDOMに追加することです(それをDOMに追加して高さと高さを取得することが重要です)。画像に非表示の表示値を設定します(機能しないため、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

最近、グラフを表す.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のようないくつかのプラグインの内部を見ているいくつかのより多くの解決策を見つけるかもしれません


1

Xaviの回答に追加するには、Paul Irishのgithub David Desandroのgitgubは、imagesLoaded()という関数を提供しています、同じ原理で一部のブラウザーのキャッシュされた画像が.load()イベントを発火しないという問題を回避します(original_src-> data_uri-> original_src切り替え)。

これは広く使用されており、定期的に更新されているため、問題の最も強力な解決策であるIMOに貢献しています。


1
imagesLoadedここで関数の更新バージョンを見つけることができます:github.com/desandro/imagesloaded
bejonbee

はい、David Desandroが現在この機能をホストしています。私に@somethingkindawierdを思い出させてくれてありがとう、私の答えを更新しました。
RobW 2011年

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/


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)

1

画像がすでに使用されている場合は、次の点に注意してください。

  1. 画像のサイズを初期に設定する

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

  2. 寸法を取得する

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


1

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;

これは、バージョン8以下のIEを除くすべてのブラウザーで機能するようです。


うん、これ以上IE8:D
Jair Reina

0

私はDioの答えを調べてみました。

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

すべての関数をasoで呼び出すようにしてください。fadeIn()のリコール関数で画像サイズを処理します。

これをありがとう。


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

?>

1
これは優れたソリューションではなく、AJAXの読み込みのために他のどのソリューションよりも時間がかかります。
halfpastfour.am、2011年

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;

乾杯!



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次元の画像を表示するのに役立ちます


0

選択した画像が読み込まれたときにイベントをトリガーするクロスブラウザーソリューションを次に示します。http://desandro.github.io/imagesloaded/ imagesLoaded()関数内で高さと幅を調べることができます。


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

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>

可能であれば、ここに数行のコードを追加することもできます。リンクはtimwによって変わる可能性があるため
Tejus Prasad

-1

元の配置または画像を変更したくない機能の場合。

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

1
これは絶対に機能しません。それは両方に対して未定義を返します
Chris Cinelli 2012年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.