Obtenez la largeur et la hauteur réelles d'une image avec JavaScript? (dans Safari/Chrome)
je crée un plugin jQuery.
Comment obtenir la largeur et la hauteur réelles de l'image avec Javascript En Safari?
œuvres suivantes avec Firefox 3, IE7 et 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();
mais dans les navigateurs Webkit comme Safari et Google Chrome les valeurs sont 0.
30 réponses
définissent la propriété height and width après le chargement de l'image. Au lieu d'utiliser les timeouts, je recommande d'utiliser l'événement onload d'une image. Voici un exemple rapide:
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.
});
pour éviter tout effet que CSS pourrait avoir sur les dimensions de l'image, le code ci-dessus fait une copie en mémoire de l'image. C'est une solution très intelligente suggérée par FDisk .
vous pouvez également utiliser le naturalHeight
et naturalWidth
HTML5 attributes.
function getOriginalWidthOfImg(img_element) {
var t = new Image();
t.src = (img_element.getAttribute ? img_element.getAttribute("src") : false) || img_element.src;
return t.width;
}
vous n'avez pas besoin de supprimer le style des attributs image ou image dimensions. Il suffit de créer un élément avec javascript et d'obtenir la largeur d'objet créée.
le problème fondamental est que les navigateurs WebKit (Safari et Chrome) chargent les informations JavaScript et CSS en parallèle. Ainsi, JavaScript peut s'exécuter avant que les effets de style de CSS aient été calculés, retournant la mauvaise réponse. A jQuery, j'ai trouvé que la solution est d'attendre le document.readyState == 'complet', .par exemple,
jQuery(document).ready(function(){
if (jQuery.browser.safari && document.readyState != "complete"){
//console.info('ready...');
setTimeout( arguments.callee, 100 );
return;
}
... (rest of function)
en largeur et en hauteur... selon ce que vous faites, vous pouvez vouloir offsetWidth et offsetHeight, qui inclure des choses comme les bordures et le rembourrage.
il y a beaucoup de discussions dans la réponse acceptée à propos d'un problème où l'événement onload
ne démarre pas si une image est chargée à partir du cache WebKit.
dans mon cas, onload
tire pour les images mises en cache, mais la hauteur et la largeur sont toujours 0. Un simple setTimeout
a résolu le problème pour moi:
$("img").one("load", function(){
var img = this;
setTimeout(function(){
// do something based on img.width and/or img.height
}, 0);
});
Je ne peux pas dire pourquoi l'événement onload
se déclenche même lorsque l'image est chargée à partir du cache (amélioration de jQuery 1.4 / 1.5?)- mais si vous rencontrez toujours ce problème, peut-être une combinaison de ma réponse et la technique var src = img.src; img.src = ""; img.src = src;
fonctionnera.
(notez que pour mes besoins, Je ne me soucie pas des dimensions prédéfinies, que ce soit dans les attributs de l'image ou les styles CSS-mais vous pourriez vouloir les supprimer, selon la réponse de Xavi. Ou clone de l'image.)
cela fonctionne pour moi (safari 3.2), en tirant de l'intérieur de l'événement window.onload
:
$(window).load(function() {
var pic = $('img');
pic.removeAttr("width");
pic.removeAttr("height");
alert( pic.width() );
alert( pic.height() );
});
vous pouvez programmatiquement obtenir l'image et vérifier les dimensions en utilisant Javascript sans avoir à jouer avec le 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';
Comment nous obtenons le droit réel dimensions sans un clin d'image réelle:
(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();});
});
fonctionne avec
Qu'en est-il des propriétés image.naturalHeight
et image.naturalWidth
?
semble fonctionner très bien en arrière un certain nombre de versions dans Chrome, Safari et Firefox, mais pas du tout dans IE8 ou même IE9.
Jquery a deux propriétés appelées naturalWidth et naturalHeight, vous pouvez utiliser de cette façon.
$('.my-img')[0].naturalWidth
$('.my-img')[0].naturalHeight
où my-img est un nom de classe utilisé pour sélectionner mon image.
comme indiqué précédemment, réponse de Xavi ne fonctionnera pas si les images sont dans le cache. Le problème répond au fait que webkit ne déclenche pas l'événement load sur les images mises en cache, donc si les attrs largeur/hauteur ne sont pas explicitement définis dans la balise img, la seule façon fiable d'obtenir les images est d'attendre que l'événement window.load
soit déclenché.
l'événement window.load
feu toujours , il est donc sûr d'accéder à la largeur / hauteur de et img après que, sans aucun pli.
$(window).load(function(){
//these all work
$('img#someId').css('width');
$('img#someId').width();
$('img#someId').get(0).style.width;
$('img#someId').get(0).width;
});
si vous avez besoin d'obtenir la taille des images chargées dynamiquement qui pourraient être mises en cache (précédemment chargées), vous pouvez utiliser la méthode Xavi plus une chaîne de requête pour déclencher un rafraîchissement du cache. L'inconvénient est qu'il va causer une autre requête au serveur, pour un img qui est déjà mis en cache et devrait être déjà disponible. Stupide 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: Si vous avez déjà un QueryString dans le img.src
, vous aurez ont analyser et ajouter un petit param pour effacer le cache.
Comme Luke Smith dit, chargement de l'image est un gâchis . Ce n'est pas fiable sur tous les navigateurs. Ce fait m'a donné beaucoup de douleur. Une image mise en cache ne déclenche pas l'Événement du tout dans certains navigateurs, de sorte que ceux qui ont dit "la charge de l'image est meilleure que setTimeout" ont tort.
la solution de Luke Smith est ici.
Et il est une discussion intéressante sur la façon dont ce désordre peut être gérée en en jQuery 1.4.
j'ai trouvé qu'il est assez fiable de régler la largeur à 0, puis d'attendre que la propriété" complète " devienne vraie et que la propriété width soit plus grande que zéro. Vous devriez aussi surveiller les erreurs.
$("#myImg").one("load",function(){
//do something, like getting image width/height
}).each(function(){
if(this.complete) $(this).trigger("load");
});
du commentaire de Chris: http://api.jquery.com/load-event /
Ma situation est probablement un peu différente. Je change dynamiquement le src d'une image via javascript et j'ai besoin de m'assurer que la nouvelle image est dimensionnée proportionnellement pour s'adapter à un conteneur fixe (dans une galerie de photos). J'ai tout d'abord juste enlevé les attributs de largeur et de hauteur de l'image après qu'elle ait été chargée (via l'événement de charge de l'image) et les ai réinitialisés après avoir calculé les dimensions préférées. Cependant, cela ne fonctionne pas en Safari et peut-être IE (Je ne l'ai pas testé en IE complètement, mais l'image ne se voit même pas, donc...).
quoi qu'il en soit, Safari conserve les dimensions de l'image précédente de sorte que les dimensions sont toujours une image derrière. Je suppose que ça a quelque chose à voir avec cache. La solution la plus simple est donc de simplement cloner l'image et de l'ajouter au DOM (il est important qu'il soit ajouté au DOM Le get the with et height). Donnez à l'image une valeur de visibilité de hidden (n'utilisez pas display none car cela ne marchera pas). Après que vous obtenez les dimensions enlèvent le clone.
Voici mon code en utilisant 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);
Cette solution fonctionne dans tous les cas.
il y a maintenant un plugin jQuery, event.special.load
, pour traiter les cas où l'événement de charge sur une image mise en cache ne fonctionne pas: http://github.com/peol/jquery.imgloaded/raw/master/ahpi.imgload.js
récemment, j'ai eu besoin de trouver la largeur et la hauteur pour définir la taille par défaut de .dialogue représentant le graphique. La Solution que j'ai utilisée était:
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 })
})
pour moi cette oeuvre en FF3, Opera 10, IE 8,7,6
P. S. Vous pouvez trouver d'autres solutions à l'intérieur de certains plugins comme LightBox ou ColorBox
pour ajouter à la réponse de Xavi, " Github de Paul Irish "gitgub de David Desandro offre une fonction appelée imagesLoaded () qui fonctionne sur les mêmes principes, et contourne le problème des images cachées de certains navigateurs ne mettant pas le feu .load() de l'événement (avec clever original_src -> data_uri -> original_src de commutation).
Il est largement utilisé et mis à jour régulièrement, ce qui contribue à la la solution la plus robuste au problème, IMO.
cela fonctionne à la fois pour les images mises en cache et chargées dynamiquement.
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.");
}
}
}
pour utiliser ce script:
function AlertImageSize(image) {
alert("Image size: " + image.width + "x" + image.height);
}
LoadImage("http://example.org/image.png", AlertImageSize);
j'ai fait quelques contourner la fonction utilitaire, en utilisant imagesLoaded jQuery plugin: 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}));
},
vous pouvez utiliser ceci en passant url, fonction et son contexte. La fonction est exécutée après que l'image est chargée et renvoie l'image créée, sa largeur et sa hauteur.
waitForImageSize("image.png", function(w,h){alert(w+","+h)},this)
si l'image est déjà utilisée, vous sholud:
-
set image symensions to initial
de l'image.css('width', 'initiale'); image.css('height', '');
-
obtenir les dimensions
var originalWidth = $(this).largeur(); var originalHeight = $(this).hauteur();
vous pouvez utiliser les propriétés naturalWidth et naturalHeight de L'élément D'image HTML. (En savoir plus info ).
vous l'utilisez comme ceci:
//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;
il semble que cela fonctionne dans tous les navigateurs sauf sur IE à partir de la version 8 et ci-dessous.
pour les fonctions où vous ne voulez pas modifier le placement original ou l'image.
$(this).clone().removeAttr("width").attr("width");
$(this).clone().removeAttr("height").attr("height);
j'ai vérifié la réponse de Dio et cela fonctionne très bien pour moi.
$('#image').fadeIn(10,function () {var tmpW = $(this).width(); var tmpH = $(this).height(); });
appelez toutes vos fonctions aso. cette poignée avec la taille de l'image dans la fonction recaller de fadeIn ().
Merci pour ça.
j'utilise une approche différente, il suffit de faire un appel Ajax au serveur pour obtenir la taille de l'image lorsque l'objet image est utilisé.
//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);
}
}
et bien sûr le code côté serveur:
<?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);
?>
Cela fonctionne de la croix-navigateur
var img = new Image();
$(img).bind('load error', function(e)
{
$.data(img, 'dimensions', { 'width': img.width, 'height': img.height });
});
img.src = imgs[i];
obtenir les dimensions en utilisant
$(this).data('dimensions').width;
$(this).data('dimensions').height;
santé!
une autre suggestion est d'utiliser imagesloaded plugin .
$("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);
}
});
/ / ce code aide à afficher l'image avec la dimension 200*274
Voici une solution de navigateur croisé qui déclenche un événement lorsque vos images sélectionnées sont chargées: http://desandro.github.io/imagesloaded / vous pouvez rechercher la hauteur et la largeur dans la fonction imagesLoaded ().
est tombé sur ce fil en essayant de trouver une réponse à ma propre question. J'ai essayé d'obtenir la largeur/hauteur d'une image dans une fonction après le chargeur, et a continué à venir avec 0. Je pense que c'est peut-être ce que vous cherchez, cependant, car cela fonctionne pour moi:
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);
}
consultez ce dépôt à github!
excellent exemple pour vérifier la largeur et la hauteur en utilisant Javascript
https://github.com/AzizAK/ImageRealSize
---Édité est demandé de certains commentaires ..
code 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);
}
et Code 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>