从 url 获取远程图像的宽度高度

因此,警报会给出宽度和高度的未定义值。我认为来自 img.onload 计算的图像的 w 和 h 值没有传递给返回的值,或者它可能返回 w 和 h 之前,onload 计算它们:

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

我怎样才能让警报显示正确的宽度和高度?

Http://jsfiddle.net/ytqxk/

141083 次浏览

Get image size with jQuery

function getMeta(url) {
$("<img/>",{
load: function() {
alert( this.width +" "+ this.height );
},
src: url
});
}

Get image size with JavaScript

function getMeta(url) {
var img = new Image();
img.onload = function() {
alert( this.width +" "+ this.height );
};
img.src = url;
}

Get image size with JavaScript (modern browsers, IE9+ )

function getMeta(url){
const img = new Image();
img.addEventListener("load", function() {
alert( this.naturalWidth +' '+ this.naturalHeight );
});
img.src = url;
}

Use like: getMeta( "http://example.com/img.jpg" );

https://developer.mozilla.org/en/docs/Web/API/HTMLImageElement

The w and h variables in img.onload function are not in the same scope with those in the getMeta() function. One way to do it, is as follows:

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

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




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

Just pass a callback as argument like this:

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

ES6

Using async/await you can do below getMeta function in sequence-like way and you can use it as follows (which is almost identical to code in your question (I add await keyword and change variable end to img, and change var to let keyword). You need to run getMeta by await only from async function (run).

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 = `width=${w}px, height=${h}px`;
size.appendChild(img);
}


run();
<div id="size" />

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 = `width=${w}px, height=${h}px`;
size.appendChild(img);
}, e=> console.log('Load error'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/7.5.2/rxjs.umd.min.js" integrity="sha512-wBEi/LQM8Pi08xK2jwHJNCiHchHnfcJao0XVQvkTGc91Q/yvC/6q0xPf+qQr54SlG8yRbRCA8QDYrA98+0H+hg==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>


<div id="size" />

Get image size with jQuery
(depending on which formatting method is more suitable for your preferences):

function getMeta(url){
$('<img/>',{
src: url,
on: {
load: (e) => {
console.log('image size:', $(e.target).width(), $(e.target).height());
},
}
});
}

or

function getMeta(url){
$('<img/>',{
src: url,
}).on({
load: (e) => {
console.log('image size:', $(e.target).width(), $(e.target).height());
},
});
}

You will can try package.

import getImageSize from 'image-size-from-url';


const {width, height} = await getImageSize('URL');