js异步获取粘贴的图片的原始宽高
原理
粘贴/拖动过来的图片都是一个元素, 所以可以通过js获取这个img元素后, 利用异步代码获取宽高, 然后在resize成为自己想要的大小:
获取宽高
async resizeImg() {
var imgObjs = document
.getElementById("editor")
.getElementsByTagName("img");
if (imgObjs) {
for (let imgObj of imgObjs) {
var getHeight_Width = function(obj){
return new Promise(
resolve => {
obj.onload = function(){
if(obj.naturalHeight){
resolve({
height:obj.naturalHeight,
width:obj.naturalWidth
})
}else{
var newImage = new Image(); // for some bad broswer
newImage.src = obj.src;
resolve({
height:newImage.height,
width:newImage.width
})
}
}
}
)}
var {width, height} = await getHeight_Width(imgObj);
resize
var maxWidth = 128;
var maxHeight = 128;
var ratio = 0;
// 检查图片是否超宽
if (width > maxWidth) {
console.log("resize width");
//计算缩放比例
ratio = maxWidth / width;
imgObj.width = maxWidth; // 设定实际显示宽度
height = height * ratio; // 计算等比例缩放后的高度
imgObj.height = height;
}
// 检查图片是否超高
if (height > maxHeight) {
console.log("resize height");
ratio = maxHeight / height;
imgObj.height = maxHeight; // 设定实际显示
width = width * ratio; // 计算等比例缩放后的
imgObj.width = width; // 设定实际显示宽度
}
Bug
这里有一个bug, 就是在for (let imgObj of imgObjs) {
遍历的时候, 因为遍历函数块中包含了异步代码, for是同步任务,for循环都结束时才会执行里面的异步函数,所以可以通过自执行函数传参(匿名函数),这样就形成了不受外界变量影响的局部作用域.解决方法如下:
for (let imgObj of imgObjs) {
console.log("process a imgObj", imgObj);
var width, height;
(async function(imgObj) {
var json = await getHeight_Width(imgObj);
width = json.width;
height = json.height;
console.log("width&height", width, height);
var maxWidth = 128;
var maxHeight = 128;
var ratio = 0;
// 检查图片是否超宽
if (width > maxWidth) {
console.log("resize width");
//计算缩放比例
ratio = maxWidth / width;
imgObj.width = maxWidth; // 设定实际显示宽度
height = height * ratio; // 计算等比例缩放后的高度
imgObj.height = height;
}
// 检查图片是否超高
if (height > maxHeight) {
console.log("resize height");
ratio = maxHeight / height;
imgObj.height = maxHeight; // 设定实际显示
width = width * ratio; // 计算等比例缩放后的
imgObj.width = width; // 设定实际显示宽度
}
})(imgObj);
}
}