it-swarm.com.de

Mit JavaScript die tatsächliche Breite und Höhe eines Bildes ermitteln? (in Safari / Chrome)

Ich erstelle ein jQuery-Plugin.

Wie erhalte ich mit Javascript in Safari eine echte Bildbreite und -höhe?

Folgendes funktioniert mit Firefox 3, IE7 und 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();

Aber in Webkit-Browsern wie Safari und Google Chrome Werte sind 0.

274
Frank Bannister

Webkit-Browser legen die Eigenschaften height und width fest, nachdem das Bild geladen wurde. Anstatt Timeouts zu verwenden, würde ich empfehlen, das Onload-Ereignis eines Bildes zu verwenden. Hier ist ein kurzes Beispiel:

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

Um die Auswirkungen von CSS auf die Bildgröße zu vermeiden, wird im obigen Code eine Kopie des Bildes im Speicher erstellt. Dies ist eine sehr clevere Lösung, die von FDisk vorgeschlagen wird.

Sie können auch die HTML5-Attribute naturalHeight und naturalWidth verwenden.

351
Xavi

Verwenden Sie die Attribute naturalHeight und naturalWidth aus HTML5 .

Zum Beispiel:

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

Funktioniert in IE9 +, Chrome, Firefox, Safari und Opera ( stats ).

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

Sie müssen den Stil nicht aus den Bild- oder Bildbemaßungsattributen entfernen. Erstellen Sie einfach ein Element mit Javascript und erhalten Sie die erzeugte Objektbreite.

60
FDisk

Das Hauptproblem besteht darin, dass WebKit-Browser (Safari und Chrome) JavaScript- und CSS-Informationen parallel laden. Daher kann JavaScript ausgeführt werden, bevor die Stileffekte von CSS berechnet wurden, und die falsche Antwort zurückgeben. In jQuery habe ich festgestellt, dass die Lösung darin besteht, zu warten, bis document.readyState == 'complete', z.

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

In Bezug auf Breite und Höhe ... je nachdem, was Sie tun, möchten Sie möglicherweise offsetWidth und offsetHeight, einschließlich Rahmen und Auffüllen.

16
Cugel

In der akzeptierten Antwort wird viel über ein Problem diskutiert, bei dem das Ereignis onload nicht ausgelöst wird, wenn ein Bild aus dem WebKit-Cache geladen wird.

In meinem Fall wird onload für zwischengespeicherte Bilder ausgelöst, aber die Höhe und Breite sind immer noch 0. Ein einfaches setTimeout hat das Problem für mich gelöst:

$("img").one("load", function(){
    var img = this;
    setTimeout(function(){
        // do something based on img.width and/or img.height
    }, 0);
});

Ich kann nicht sagen, warum das onload -Ereignis ausgelöst wird, auch wenn das Image aus dem Cache geladen wird (Verbesserung von jQuery 1.4/1.5?) - aber wenn dieses Problem weiterhin auftritt, kann eine Kombination von auftreten meine antwort und der var src = img.src; img.src = ""; img.src = src; Technik wird funktionieren.

(Beachten Sie, dass es mir für meine Zwecke nicht um vordefinierte Dimensionen geht, weder in den Bildattributen noch in den CSS-Stilen. Sie können diese jedoch entfernen, wie in der Antwort von Xavi angegeben. Oder das Bild klonen.)

16
JKS

dies funktioniert für mich (Safari 3.2), indem ich aus dem window.onload - Ereignis heraus feuere:

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

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

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

Sie können das Bild programmgesteuert abrufen und die Abmessungen mit Javascript überprüfen, ohne sich mit dem DOM anlegen zu müssen.

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

Wie wäre es mit image.naturalHeight und image.naturalWidth Eigenschaften?

Scheint in Chrome, Safari und Firefox ziemlich gut zu funktionieren, aber in IE8 oder sogar IE9 überhaupt nicht.

6

So erhalten wir die richtigen realen Dimensionen ohne ein blinzelndes reales Bild:

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

Es funktioniert mit <img class = "toreaddimensions" ...

5
Fox

Jquery hat zwei Eigenschaften, naturalWidth und naturalHeight, die Sie auf diese Weise verwenden können.

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

Wobei my-img ein Klassenname ist, der zur Auswahl meines Bildes verwendet wird.

4
Samuel Santos

Wie bereits erwähnt, funktioniert Xavi-Antwort nicht, wenn sich Bilder im Cache befinden. Das Problem tritt auf, wenn das Webkit das Ladeereignis für zwischengespeicherte Bilder nicht auslöst. Wenn also die Breite/Höhe-Attribute nicht explizit im img-Tag festgelegt sind, können Sie die Bilder nur zuverlässig abrufen, indem Sie auf das Ereignis window.load Warten gefeuert werden.

Das Ereignis window.load Wird immer ausgelöst , so dass Sie ohne Trick sicher auf die Breite/Höhe von und img zugreifen können.

$(window).load(function(){

   //these all work

   $('img#someId').css('width');
   $('img#someId').width();
   $('img#someId').get(0).style.width;
   $('img#someId').get(0).width; 

});

Wenn Sie die Größe der dynamisch geladenen Bilder abrufen möchten, die möglicherweise zwischengespeichert werden (zuvor geladen), können Sie die Xavi-Methode plus eine Abfragezeichenfolge verwenden, um eine Cache-Aktualisierung auszulösen. Der Nachteil ist, dass es eine weitere Anfrage an den Server für ein Bild gibt, das bereits zwischengespeichert ist und bereits verfügbar sein sollte. Dummes 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: Wenn Sie bereits einen QueryString in img.src haben, müssen Sie parsen und den zusätzlichen Parameter hinzufügen, um den Cache zu leeren.

3
xmarcos
$("#myImg").one("load",function(){
  //do something, like getting image width/height
}).each(function(){
  if(this.complete) $(this).trigger("load");
});

Aus Chris 'Kommentar: http://api.jquery.com/load-event/

2
Jerome Jaglale

Meine Situation ist wahrscheinlich etwas anders. Ich ändere dynamisch den Quellcode eines Bildes über Javascript und muss sicherstellen, dass das neue Bild proportional zur Größe eines festen Containers (in einer Fotogalerie) angepasst ist. Ich habe zunächst nur die Attribute width und height des Bildes entfernt, nachdem es geladen wurde (über das Ladeereignis des Bildes), und diese zurückgesetzt, nachdem die bevorzugten Abmessungen berechnet wurden. Dies funktioniert jedoch nicht in Safari und möglicherweise IE (Ich habe es nicht gründlich in IE getestet, aber das Bild wird nicht einmal angezeigt, also. ..).

Auf jeden Fall behält Safari die Abmessungen des vorherigen Bildes bei, sodass die Abmessungen immer ein Bild dahinter sind. Ich gehe davon aus, dass dies etwas mit Cache zu tun hat. Die einfachste Lösung besteht also darin, das Bild einfach zu klonen und zum DOM hinzuzufügen (es ist wichtig, dass es zum DOM hinzugefügt wird, um das with und die height zu erhalten). Weisen Sie dem Bild den Sichtbarkeitswert "Versteckt" zu (verwenden Sie "Keine Anzeige" nicht, da dies nicht funktioniert). Nachdem Sie die Dimensionen erhalten haben, entfernen Sie den Klon.

Hier ist mein Code mit 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);

Diese Lösung funktioniert auf jeden Fall.

2
Duane Comeaux

Wie Luke Smith sagt, Bildlast ist ein Durcheinander . Es ist nicht bei allen Browsern zuverlässig. Diese Tatsache hat mir große Schmerzen bereitet. Ein zwischengespeichertes Bild löst das Ereignis in einigen Browsern überhaupt nicht aus, daher sind diejenigen, die sagten, dass "Bildladen besser ist als setTimeout", falsch.

Luke Smiths Lösung ist hier.

Und es gibt eine interessante Diskussion darüber, wie dieses Durcheinander in jQuery 1.4 behandelt werden könnte.

Ich habe festgestellt, dass es ziemlich zuverlässig ist, die Breite auf 0 zu setzen und dann zu warten, bis die Eigenschaft "complete" auf "true" gesetzt ist und die Eigenschaft width größer als Null ist. Sie sollten auch auf Fehler achten.

2
Nosredna

Ich habe einige Workaround-Utility-Funktionen mit dem imagesLoaded-JQuery-Plugin ausgeführt: 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}));
            },

Sie können dies verwenden, indem Sie URL, Funktion und Kontext übergeben. Die Funktion wird ausgeführt, nachdem das Bild geladen wurde und das erstellte Bild mit seiner Breite und Höhe zurückgegeben wurde.

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

Kürzlich musste ich Breite und Höhe finden, um die Standardgröße des .dialog-Diagramms festzulegen. Lösung, die ich benutze, war:

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

Bei mir funktioniert das in FF3, Opera 10, IE 8,7,6

P.S. Möglicherweise finden Sie weitere Lösungen in Plugins wie LightBox oder ColorBox

1
SDemonUA

Wenn das Bild bereits verwendet wird, sollten Sie Folgendes tun:

  1. bildsimulationen auf initial setzen

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

  2. maße erhalten

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

1

Sie können die Eigenschaften naturalWidth und naturalHeight des HTML-Bildelements verwenden. (Hier ist mehr info ).

Du würdest es so benutzen:

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

Es scheint, dass dies in allen Browsern funktioniert, außer in IE ab Version 8 und darunter.

1
Jair Reina

Dies funktioniert sowohl für zwischengespeicherte als auch für dynamisch geladene Bilder.

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

So verwenden Sie dieses Skript:

function AlertImageSize(image) {
  alert("Image size: " + image.width + "x" + image.height);
}
LoadImage("http://example.org/image.png", AlertImageSize);

Demo: http://jsfiddle.net/9543z/2/

1
CheeseSucker

Es gibt jetzt ein jQuery-Plugin, event.special.load, um Fälle zu behandeln, in denen das Ladeereignis auf einem zwischengespeicherten Image nicht ausgelöst wird: http://github.com/peol/jquery.imgloaded/raw/master/ahpi.imgload.js

1
S P

Um zu Xavis Antwort hinzuzufügen, Paul Irishs Github David Desandros gitgub bietet eine Funktion namens imagesLoaded () , die nach den gleichen Prinzipien arbeitet und das Problem umgeht, dass die zwischengespeicherten Bilder einiger Browser das Ereignis .load () nicht auslösen (mit cleverem original_src -> data_uri - > original_src Umschaltung).

Es wird häufig verwendet und regelmäßig aktualisiert, was dazu beiträgt, dass es die robusteste Lösung für das Problem ist, IMO.

1
RobW

Bin über diesen Thread gestolpert und habe versucht, eine Antwort auf meine eigene Frage zu finden. Ich habe versucht, die Breite/Höhe eines Bildes in einer Funktion NACH dem Ladevorgang zu ermitteln, und habe immer wieder 0 gefunden. Ich glaube, das könnte genau das sein, wonach Sie suchen, da es für mich funktioniert:

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

// Dieser Code hilft beim Anzeigen von Bildern mit einer Dimension von 200 * 274

0
Eranda

Ich habe die Antwort von Dio überprüft und es funktioniert großartig für mich.

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

Stellen Sie sicher, dass Sie auch alle Ihre Funktionen aufrufen. die mit der Bildgröße in der Recaller-Funktion von fadeIn () umgehen.

Danke dafür.

0
drublic

Schauen Sie sich dieses Repository in Github an!

Tolles Beispiel, um die Breite und Höhe mit Javascript zu überprüfen

https://github.com/AzizAK/ImageRealSize

--- Bearbeitet wird von einigen Kommentaren angefordert ..

Javascript-Code:

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

und HTML-Code:

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

Ein weiterer Vorschlag ist die Verwendung von imagesLoaded plugin .

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

Dies funktioniert browserübergreifend

var img = new Image();
$(img).bind('load error', function(e)
{
    $.data(img, 'dimensions', { 'width': img.width, 'height': img.height });                    
});
img.src = imgs[i];              

holen Sie sich die Dimensionen mit

$(this).data('dimensions').width;
$(this).data('dimensions').height;

Prost!

0
foxybagga

Ich benutze einen anderen Ansatz, rufe einfach den Ajax-Server an, um die Bildgröße abzurufen, wenn ein Bildobjekt verwendet wird.

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

und natürlich serverseitiger Code:

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

Hier ist eine browserübergreifende Lösung, die ein Ereignis auslöst, wenn Ihre ausgewählten Bilder geladen werden: http://desandro.github.io/imagesloaded/ Sie können die Höhe und Breite in der Funktion imagesLoaded () nachschlagen.

0
Paul Mason

Für Funktionen, bei denen Sie die ursprüngliche Platzierung oder das Bild nicht ändern möchten.

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