문제

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 브라우저는 이미지가로드 된 후 높이와 너비 속성을 설정합니다. 타임 아웃을 사용하는 대신 이미지의 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 속성.

다른 팁

사용 naturalHeight 그리고 naturalWidth 속성 html5.

예를 들어:

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

IE9+, Chrome, Firefox, Safari 및 Opera에서 작동합니다.통계).


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로 요소를 만들고 생성 된 객체 너비를 가져 오십시오.

루트 문제는 WebKit 브라우저 (Safari 및 Chrome)가 JavaScript 및 CSS 정보를 병렬로로드한다는 것입니다. 따라서 CSS의 스타일 효과가 계산되기 전에 JavaScript가 실행될 수 있으며, 잘못된 답변을 반환합니다. 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) 

너비와 높이가 진행되는 한 ... 당신이하고있는 일에 따라, 당신은 국경과 패딩과 같은 것들을 포함하는 오프셋 폭과 오프 스테 오전을 원할 수 있습니다.

인정 된 답변에는 문제가있는 문제에 대한 많은 토론이 있습니다. onload WebKit 캐시에서 이미지가로드되면 이벤트가 시작되지 않습니다.

나의 경우에는, 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의 답변에 따라이를 제거하거나 이미지를 복제 할 수 있습니다.)

이것은 내에서 발사하여 나를 위해 작동합니다 (Safari 3.2) window.onload 이벤트:

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

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

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

프로그래밍 방식으로 이미지를 가져 와서 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';

는 어때 image.naturalHeight 그리고 image.naturalWidth 속성?

Chrome, Safari 및 Firefox에서는 꽤 많은 버전을 다시 작동시키는 것처럼 보이지만 IE8 또는 IE9에서는 전혀 그렇지 않습니다.

실제 이미지없이 실제 차원을 얻는 방법 :

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

그것은 함께 작동합니다

JQuery에는 Naturalwidth와 NaturalHeight라는 두 가지 속성이 있습니다. 이런 식으로 사용할 수 있습니다.

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

여기서 My-IMG는 내 이미지를 선택하는 데 사용되는 클래스 이름입니다.

앞에서 언급했듯이 Xavi 답변 이미지가 캐시에 있으면 작동하지 않습니다. 이 문제는 캐시 된 이미지에서로드 이벤트를 발사하지 않는 WebKit에 응답하므로 IMG 태그에 너비/높이 atts가 명시 적으로 설정되지 않으면 이미지를 기다리는 유일한 방법은 window.load 해고 될 이벤트.

그만큼 window.load 이벤트가 시작됩니다 언제나, 그 후에는 속임수없이 IMG와 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;

});

추신 : 쿼리 스트링이있는 경우 img.src 이미, 당신은해야 할 것입니다 구문 분석하십시오 캐시를 지우려면 여분의 매모를 추가하십시오.

루크 스미스가 말했듯이 이미지로드는 엉망입니다. 모든 브라우저에서 신뢰할 수있는 것은 아닙니다. 이 사실은 나에게 큰 고통을 주었다. 캐시 된 이미지는 일부 브라우저에서 이벤트를 전혀 실행하지 않으므로 "이미지로드가 설정 타임 아웃보다 낫다"고 말하는 사람들은 잘못된 것입니다.

루크 스미스의 솔루션은입니다 여기.

그리고 있습니다 흥미로운 토론 jQuery 1.4 에서이 혼란이 어떻게 처리 될 수 있는지에 대해.

나는 너비를 0으로 설정하는 것이 매우 신뢰할 수 있음을 발견 한 다음 "완전한"속성이 사실이 될 때까지 기다리고 너비 속성이 0보다 크게 나타납니다. 오류도 지켜봐야합니다.

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

내 상황은 아마도 조금 다를 것입니다. JavaScript를 통해 이미지의 SRC를 동적으로 변경하고 있으며 새로운 이미지가 고정 컨테이너 (사진 갤러리)에 맞게 크기가 크기를 보장해야합니다. 처음에는 이미지가로드 된 후 이미지의 폭과 높이 속성을 제거하고 (이미지의로드 이벤트를 통해) 선호하는 치수를 계산 한 후 이들을 재설정했습니다. 그러나 그것은 사파리에서 작동하지 않고 IE에서 작동하지 않습니다 (IE에서 철저히 테스트하지는 않았지만 이미지는 표시되지 않습니다 ...).

어쨌든 Safari는 이전 이미지의 치수를 유지하므로 크기는 항상 하나의 이미지입니다. 나는 이것이 캐시와 관련이 있다고 가정합니다. 따라서 가장 간단한 솔루션은 이미지를 복제하여 DOM에 추가하는 것입니다 (Get the the with and Height에 DOM에 추가하는 것이 중요합니다). 이미지에 숨겨진 가시성 값을 제공하십시오 (디스플레이는 작동하지 않기 때문에 디스플레이를 사용하지 마십시오). 치수를 얻은 후 클론을 제거하십시오.

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

이 솔루션은 어쨌든 작동합니다.

이제 jQuery 플러그인이 있습니다. event.special.load, 캐시 된 이미지의로드 이벤트가 발사되지 않는 경우를 처리하려면 다음과 같습니다. http://github.com/peol/jquery.imgloaded/raw/master/ahpi.imgload.js

최근에 그래프를 나타내는 .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와 같은 일부 플러그인 내부를 보면 더 많은 솔루션을 찾을 수 있습니다.

Xavi의 답변에 추가하려면 Paul Irish의 Github David Desandro의 Gitgub은 ImagesLoaded ()라는 기능을 제공합니다. 이는 동일한 원칙에 따라 작동하며 .LOAD () 이벤트를 발사하지 않는 일부 브라우저의 캐시 이미지의 문제를 해결합니다 (Clever Original_Src-> data_uri-> Original_Src Switching).

정기적으로 널리 사용되고 업데이트되어 문제에 대한 가장 강력한 솔루션 인 IMO에 기여합니다.

이것은 캐시 된 이미지와 동적으로로드 된 이미지 모두에서 작동합니다.

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/

이미지로드 된 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. 이미지 동시에 초기로 설정하십시오

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

  2. 치수를 얻으십시오

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

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를 제외한 모든 브라우저에서 작동하는 것 같습니다.

원래 배치 또는 이미지를 변경하고 싶지 않은 기능의 경우.

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

나는 Dio의 답변을 확인했고 그것은 나에게 훌륭하게 작동합니다.

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

모든 기능을 ASO라고 부릅니다. 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);

?>

이것은 크로스 브라우저에서 작동합니다

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;

건배!

또 다른 제안은 사용하는 것입니다 이미지로드 된 플러그인.

$("img").imagesLoaded(function(){
alert( $(this).width() );
alert( $(this).height() );
});
$(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 차원으로 이미지를 표시하는 데 도움이됩니다.

다음은 선택한 이미지가로드 될 때 이벤트를 트리거하는 크로스 브라우저 솔루션입니다. http://desandro.github.io/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);
}

Github 에서이 저장소를 확인하십시오!

JavaScript를 사용하여 너비와 높이를 확인하는 좋은 예

https://github.com/azizak/imagerealsize

--- 편집 된 댓글에서 편집이 요청됩니다 ..

자바 스크립트 코드 :

 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>
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top