面試題:JS 獲取圖片寬高

通常用於審覈後臺,好比說要求圖片在必定區間內才能加精
也用於在 canvas 中裁圖時計算縮放比例canvas

JS 獲取圖片寬高

獲取 naturalWidth(callback 版本)

方案爲獲取 naturalWidth。那麼 naturalWidthwidth 有什麼不一樣?安全

  • naturalWidth 標識圖片的原始寬高。
  • width 由於歷史問題,標識的實際上是 DOM 元素寬高。
  • 由於 img 標籤會被圖片撐開,因此測試

    • 在不設置 width 屬性時,width == naturalWidth
    • 在設置了 width 屬性時,width != naturalWidth
getImgRawSize = (img, cb) => {
    var _image = img;
    if (_image instanceof HTMLImageElement) {
        // 傳入的是 DOM 對象
        if (_image.naturalWidth) {
            // 推薦使用 naturalWidth ,由於該值返回的是原始值,不會被屬性影響
            return cb({width: _image.naturalWidth, height: _image.naturalHeight})
        }
        if (_image.complete) {
            // 若是沒有 naturalWidth 且圖片已加載完成,那麼很大概率是不支持
            // 爲了防止被屬性影響,咱們要用空白的標籤從新加載
            img = img.src
        }else{
            // 沒有加載完成的話直接用
            _image = img;
        }
    }
    if(typeof img == 'string'){
        // 傳入的是 url
        _image = new Image();
        _image.src = img
    }
    _image.onload = _ => {
        // 若是想要安全的,能夠考慮拿不到naturalWidth就是用新的 Image 來獲取
        cb({width: _image.naturalWidth || _image.width, height: _image.naturalHeight||_image.height})
    }
    _image.onerror = _ => {
        cb({width: 0, height: 0})
    }
}

測試截圖

image.png

測試用例

getImgRawSize('https://www.lilnong.top/static/img/ml-active-btn1.png', v=>console.log(1, v))
getImgRawSize('https://www.lilnong.top/static/img/ml-active-btn6.png', v=>console.log(2, v))

// 測試未加載
img = new Image()
img.src = 'https://www.lilnong.top/static/img/defaultmatch.png'
getImgRawSize(img, v=>console.log(3,v))


// 測試未加載且設置寬高
img = new Image()
img.width = 10
img.height = 20
img.src = 'https://www.lilnong.top/static/img/QQ_20190301172837.jpg'
getImgRawSize(img, v=>console.log(4,v))


// 測試已加載
img = new Image()
img.src = 'https://www.lilnong.top/static/img/Rectangle%2010.png'
img.onload = ()=>getImgRawSize(img, v=>console.log(5,v))

// 測試已加載且設置寬高
img = new Image()
img.width = 10
img.height = 20
img.src = 'https://www.lilnong.top/static/img/ml-btn6.png'
img.onload = ()=>getImgRawSize(img, v=>console.log(6,v))

獲取 naturalWidth(Promise 版本)

實現和上面是一致的,只不過改成了 Promise 版本。url

getImgRawSize = (img) => {
    return Promise.resolve(new Promise(function(reslove, reject){
        var _image = img;
        if (_image instanceof HTMLImageElement) {
            if (_image.naturalWidth) return reslove({width: _image.naturalWidth, height: _image.naturalHeight})
            img = img.src
        }
        if(typeof img == 'string'){
            _image = new Image();
            _image.src = img
        }
        _image.onload = _ =>  reslove({width: _image.naturalWidth || _image.width, height: _image.naturalHeight||_image.height})
        _image.onerror = _ =>  reject({width: 0, height: 0})
    }))
}

測試截圖

image.png

測試用例

getImgRawSize('https://www.lilnong.top/static/img/ml-active-btn1.png').then(v=>console.log(1, v))
getImgRawSize('https://www.lilnong.top/static/img/ml-active-btn6.png').then(v=>console.log(2, v))

// // 測試未加載
img = new Image()
img.src = 'https://www.lilnong.top/static/img/defaultmatch.png'
getImgRawSize(img).then(v=>console.log(3, v))


// 測試未加載且設置寬高
img = new Image()
img.width = 10
img.height = 20
img.src = 'https://www.lilnong.top/static/img/QQ_20190301172837.jpg'
getImgRawSize(img).then(v=>console.log(4, v))


// 測試已加載
img = new Image()
img.src = 'https://www.lilnong.top/static/img/Rectangle%2010.png'
img.onload = ()=>getImgRawSize(img).then(v=>console.log(5, v))

// 測試已加載且設置寬高
img = new Image()
img.width = 10
img.height = 20
img.src = 'https://www.lilnong.top/static/img/ml-btn6.png'
img.onload = ()=>getImgRawSize(img).then(v=>console.log(6, v))
相關文章
相關標籤/搜索