中秋剛過去幾天,首先在這里祝與親人團聚的朋友們闔家歡樂,告訴和我一樣獨在異鄉的青年們不要孤單,你不是一個人,在外也要好好生活,每逢佳節和朋友們一起吃點好吃的^?_?^
最近工作中遇到一個將圖片轉為base64的格式發給native的需求,代碼起先是我旁邊的大佬寫的,他是使用url-loader實現的,由于大佬休假了,接下來的工作交接給我,根據墨菲定律,emm。。。出bug了,url-loader轉出來的碼不太正確,我仔細閱讀了文檔,又關鍵詞搜索了一圈,未果,(emm。。。我現在還沒找到原因,有知道的小伙伴歡迎留言),時間緊張,只好另謀出路。
于是,我打算采取html5的canvas,將圖片繪制到畫布上,然后用canvas的 toDataURL 方法。
在網上看了示例,還結合大佬的異步加載代碼好好優化了下。
let canvas;
function initCanvas() {
if (!canvas) {
canvas = document.createElement('canvas')
}
return canvas
}
async function loadImg(src) {
let img = new Image()
img.src = src
return new Promise((resolve, reject) => {
img.onload = function() {
resolve(img)
}
img.onerror = function(error) {
reject(error)
}
})
}
function toBase64(img, outputFormat) {
let ctx = canvas.getContext('2d')
canvas.width = img.width
canvas.height = img.height
ctx.drawImage(img, 0, 0)
return canvas.toDataURL(outputFormat || 'image/jpg')
}
async function convertImgToBase64(url, outputFormat) {
initCanvas()
if (!canvas.toDataURL || typeof canvas.toDataURL !== 'function') {
throw new Error('method not supported')
}
const img = await loadImg(url, 'Anonymous')
return toBase64(img, outputFormat)
}
自我感覺良好,但是運行之后報錯了
Uncaught DOMException: Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported.
谷歌翻譯:canvas無法執行toDataURL方法:污染的畫布無法輸出
看不懂是吧?不要著急,一般當我們遇到這種一長串且有明顯關鍵詞的報錯,你應該松一口氣,這類錯誤一般直接貼上google下就可以找到答案。比如:https://stackoverflow.com/questions/22710627/tainted-canvases-may-not-be-exported
高票答案讓加上crossOrigin,一個針對
img
、video
等的跨域屬性,這篇文章講得還不錯,就是說只要加上crossOrigin: ''
屬性,不管值是anonymous
、‘’
或者abc
都可以,相對于告訴對方服務器,你不需要帶任何非匿名信息過來。例如cookie,因此,當前瀏覽器肯定是安全的。好了,問題圓滿解決,oh,不,不圓滿,我還不知道url-loader為啥沒實現:(,我回頭請教下我們大佬再來補充吧。
補充:
經過大家的共同探討,問題得到了解決,需要在url中加入“!”
const shareLogo = require('!url-loader!../assets/logo.jpeg');
具體原因可以閱讀url-loader is encoding path instead of image#43
總結下就是:
由于我們webpack中的配置,用于提高性能
{
test: /\.(png|svg)$/,
loader: 'url-loader',
query: {
limit: 10000,
},
}
如果圖片較多,會發很多http請求,會降低頁面性能。這個問題可以通過url-loader解決。url-loader會將引入的圖片編碼,生成dataURl。相當于把圖片數據翻譯成一串字符。再把這串字符打包到文件中,最終只需要引入這個文件就能訪問圖片了。當然,如果圖片較大,編碼會消耗性能。因此url-loader提供了一個limit參數,小于limit字節的文件會被轉為DataURl,大于limit的還會使用file-loader進行copy。
所以debug時我們發現圖片被轉碼了2次:
第一個loader(url)對圖像進行編碼并返回編碼圖像的路徑
第二個loader(文件)是對編碼圖像進行編碼的路徑
在簡書上發布相關文章是對自己不斷學習的鼓勵;如有什么寫得不對的地方,歡迎批評指正;給我點贊的都是小可愛^?_?^