web-dev-qa-db-ja.com

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

272
Frank Bannister

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 によって示唆された非常に賢い解決策です。

naturalHeightおよびnaturalWidth HTML5属性も使用できます。

351
Xavi

HTML5naturalHeightおよびnaturalWidth属性を使用してください。

例えば:

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

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

279
sandstrom

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で要素を作成し、作成されたオブジェクトの幅を取得します。

59
FDisk

根本的な問題は、WebKitブラウザ(SafariとChrome)がJavaScriptとCSSの情報を並行して読み込むことです。そのため、CSSのスタイル効果が計算される前にJavaScriptが実行され、間違った答えが返されることがあります。 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が必要かもしれません。それらはボーダーとパディングのようなものを含みます。

16
Cugel

画像が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の答えに従ってそれらを削除することもできます。または画像を複製します。)

16
JKS

window.onloadイベント内から起動することで、これは私にとってはうまくいきます(safari 3.2):

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

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

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

あなたはプログラム的に画像を取得し、まったくDOMを台無しにする必要なしにJavascriptを使って寸法をチェックすることができます。

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';
8
Yëco

image.naturalHeightimage.naturalWidthプロパティはどうですか?

Chrome、Safari、Firefoxではかなりの数のバージョンがうまく動作しているように見えますが、IE8やIE9ではまったく動作しません。

6

実画像を点滅させずに正しい実寸を取得する方法

(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
Fox

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

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

My-imgは、画像を選択するためのクラス名です。

4
Samuel Santos

前述のように、 Xaviの答え は、画像がキャッシュにあると機能しません。この問題はwebkitがキャッシュされた画像でloadイベントを発生させないことに対応しているので、幅/高さattrsがimgタグで明示的に設定されていない場合、画像を取得する唯一の信頼できる方法はwindow.loadイベントが発生するのを待つことです。

window.loadイベントは常に/を発生させるので、そのあとのwidth/heightと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がある場合は、それを 解析し 、キャッシュをクリアするための追加のパラメータを追加する必要があります。

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

2
Jerome Jaglale

私の状況はおそらくちょっと違います。私はjavascriptを使って画像のソースを動的に変更していて、新しい画像が(フォトギャラリーの)固定コンテナに合うように比例した大きさになるようにする必要があります。画像の読み込み後(画像の読み込みイベントを介して)、まず画像の幅と高さの属性を削除し、好みの寸法を計算した後にこれらをリセットします。ただし、それはSafariでは機能せず、おそらくIEでテストされていません(私はIEで徹底的にテストしていませんが、画像は表示されない、など)。

とにかく、Safariは前の画像の寸法を保持しているので、寸法は常に1画像後ろになります。これはキャッシュと関係があると思います。そのため、最も簡単な解決策は、イメージを複製してDOMに追加することです(DOMに追加して高さを取得することが重要です)。画像の可視性を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);

この解決策はどのような場合でも機能します。

2
Duane Comeaux

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

Luke Smithの解決策は です。

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

幅を0に設定してから、 "complete"プロパティがtrueになり、widthプロパティが0より大きくなるのを待つのがかなり信頼できることがわかりました。あなたもエラーに注意するべきです。

2
Nosredna

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、functionそしてそのコンテキストを渡すことでこれを使うことができます。 imageがロードされて、作成されたimage、その幅と高さを返したあと、機能は実行されます。

waitForImageSize("image.png", function(w,h){alert(w+","+h)},this)
1
Zdeněk Mlčoch

最近、グラフを表す.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、オペラ10、IE 8,7,6で動作します

P.Sあなたはライトボックスやカラーボックスのようないくつかのプラグインの中を見ていくつかの他の解決策を見つけるかもしれません

1
SDemonUA

画像が既に使用されている場合は、sholud:

  1. 画像の寸法を初期値に設定

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

  2. 寸法を取得

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

1

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を除くすべてのブラウザで動作するようです。

1
Jair Reina

これは、キャッシュされた画像と動的に読み込まれた画像の両方で機能します。

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
CheeseSucker

キャッシュされたイメージのloadイベントが発生しない場合に対処するためのjQueryプラグインevent.special.loadがあります。 http://github.com/peol/jquery.imgloaded/raw /master/ahpi.imgload.js

1
S P

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

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

1
RobW

私自身の質問に対する答えを見つけようとしているこのスレッドにつまずいた。私はローダーの後の関数で画像の幅/高さを取得しようとしていました、そして、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
$(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
Eranda

私はDioの答えをチェックアウトしました、そしてそれは私にとって素晴らしい仕事です。

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

すべての関数を必ずasoと呼ぶようにしてください。 fadeIn()の再呼び出し関数の画像サイズでそのハンドル。

これをありがとう。

0
drublic

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>

別の提案は imagesLoadedプラグイン を使うことです。

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

これはクロスブラウザで動作します

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
foxybagga

私は別の方法を使用します。画像オブジェクトが使用されているときに画像サイズを取得するために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
damijanc

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

0
Paul Mason

元の配置や画像を変更したくない機能のために。

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