101 votes

Obtenir la largeur hauteur de l'image distante à partir de l'URL

Donc l'alerte donne des valeurs non définies pour la largeur et la hauteur. Je pense que les valeurs w et h de l'image issues du calcul img.onload ne sont pas transmises aux valeurs à retourner, ou elles pourraient retourner w et h avant que le onload ne les calcule :

function getMeta(url){
 var w; var h;
 var img=new Image;
 img.src=url;
 img.onload=function(){w=this.width; h=this.height;};
 return {w:w,h:h}    
}

// "http://snook.ca/files/mootools_83_snookca.png" //1024x678
// "http://shijitht.files.wordpress.com/2010/08/github.png" //128x128

var end = getMeta("http://shijitht.files.wordpress.com/2010/08/github.png");
var w = end.w;
var h = end.h;
alert(w+'width'+h+'height');

Comment puis-je faire en sorte que l'alerte affiche la largeur et la hauteur correctes ?

http://jsfiddle.net/YtqXk/

172voto

Roko C. Buljan Points 46488

Obtenir la taille de l'image avec JavaScript

Pour lire les données d'une image, vous devez vous assurer qu'elle est d'abord chargée. Voici une approche basée sur des rappels et deux solutions basées sur des promesses :

Rappel

const getMeta = (url, cb) => {
  const img = new Image();
  img.onload = () => cb(null, img);
  img.onerror = (err) => cb(err);
  img.src = url;
};

// Utilisation :
getMeta("https://i.sstatic.net/qCWYU.jpg", (err, img) => {
  console.log(img.naturalWidth, img.naturalHeight);
});

Utilisation de l'load Event listener (Promise)

const getMeta = (url) =>
  new Promise((resolve, reject) => {
    const img = new Image();
    img.onload = () => resolve(img);
    img.onerror = (err) => reject(err);
    img.src = url;
  });

// Exemple d'utilisation : 
;(async() => {
  const img = await getMeta('https://i.sstatic.net/qCWYU.jpg');
  console.dir(img.naturalHeight + ' ' + img.naturalWidth);
});

Utilisation de HTMLImageElement.decode() (Promise)

const getMeta = async (url) => {
  const img = new Image();
  img.src = url;
  await img.decode();  
  return img
};

// Exemple d'utilisation :
getMeta('https://i.sstatic.net/qCWYU.jpg').then(img => {
  console.dir(img.naturalHeight +' '+ img.naturalWidth);
});

35voto

feychou Points 571

Il suffit de passer une fonction de rappel en argument comme ceci :

function getMeta(url, callback) {
    const img = new Image();
    img.src = url;
    img.onload = function() { callback(this.width, this.height); }
}
getMeta(
  "http://snook.ca/files/mootools_83_snookca.png",
  (width, height) => { alert(width + 'px ' + height + 'px') }
);

28voto

Kamil Kiełczewski Points 6496

ES6

En utilisant async/await, vous pouvez exécuter la fonction getMeta de manière séquentielle et l'utiliser comme suit (qui est presque identique au code de votre question (j'ajoute le mot-clé await et change la variable end en img, et change var en mot-clé let). Vous devez exécuter getMeta avec await uniquement à partir d'une fonction async (exécuter).

function getMeta(url) {
    return new Promise((resolve, reject) => {
        let img = new Image();
        img.onload = () => resolve(img);
        img.onerror = () => reject();
        img.src = url;
    });
}

async function run() {

  let img = await getMeta("http://shijitht.files.wordpress.com/2010/08/github.png");

  let w = img.width;
  let h = img.height; 

  size.innerText = `largeur=${w}px, hauteur=${h}px`;
  size.appendChild(img);
}

run();

Rxjs

const { race, fromEvent, map, mergeMap, of } = rxjs;

function getMeta(url) {
    return of(url).pipe(
        mergeMap((path) => {
            const img = new Image();
            let load = fromEvent(img, 'load').pipe(map(_=> img))
            let error = fromEvent(img, 'error').pipe(mergeMap((err) => throwError(() => err)));
            img.src = path;

            return race(load, error);
        })
    );
}

let url = "http://shijitht.files.wordpress.com/2010/08/github.png";

getMeta(url).subscribe(img=> { 
  let w = img.width;
  let h = img.height; 

  size.innerText = `largeur=${w}px, hauteur=${h}px`;
  size.appendChild(img);
}, e=> console.log('Erreur de chargement'))

13voto

Panagiotis Panagi Points 4986

Les variables w et h dans la fonction img.onload ne sont pas dans le même scope que celles dans la fonction getMeta(). Une façon de le faire, est comme suit:

Fiddle: http://jsfiddle.net/ppanagi/28UES/2/

function getMeta(varA, varB) {
    if (typeof varB !== 'undefined') {
       alert(varA + ' largeur ' + varB + ' hauteur');
    } else {
       var img = new Image();
       img.src = varA;
       img.onload = getMeta(this.width, this.height);
    }
}

getMeta("http://snook.ca/files/mootools_83_snookca.png");

0voto

almaceleste Points 243

Obtenir la taille de l'image avec jQuery
(selon la méthode de formatage la plus appropriée pour vos préférences):

function getMeta(url){
    $('',{
        src: url,
        on: {
            load: (e) => {
                console.log('taille de l'image:', $(e.target).width(), $(e.target).height());
            },
        }
    });
}

ou

function getMeta(url){
    $('',{
        src: url,
    }).on({
        load: (e) => {
            console.log('taille de l'image:', $(e.target).width(), $(e.target).height());
        },
    });
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X