1. 程式人生 > 其它 >前端效能優化 —— 使用 BMP 圖片代替 canvas.toDataURL

前端效能優化 —— 使用 BMP 圖片代替 canvas.toDataURL

前端開發中有時需要將 canvas 的內容匯出成圖片檔案,例如供 CSS 使用,通常會使用 canvas.toDataURL,相容性好並且簡單。

不過 canvas.toDataURL 顯然是非常低效的:首先要將影象編碼成 PNG 格式,然後再編碼成 Base64,使用時又要解碼 Base64 和 PNG,一來一往浪費大量開銷,並且超長的 URL 也不美觀。當然,使用 canvas.toBlob 倒是可以避免 Base64 轉換和超長的 URL,但 PNG 轉換仍不可避免,而這是最耗效能的。

既然圖片只在本地使用,壓縮顯然毫無必要,為什麼不使用更簡單的 BMP 格式?雖然 canvas 並不支援匯出 BMP 格式,但主流瀏覽器都能顯示 BMP 圖片,而且 BMP 本身也支援透明通道,因此完全可以代替 PNG。

BMP 格式非常簡單,只需在畫素資料前加個檔案頭就可以。頭結構可參考 https://en.wikipedia.org/wiki/BMP_file_format#Example_2

其中有些欄位是可選的,不用設定。也有幾個比較重要的:

  • BMP 預設從下往上顯示,高度取負可從上往下顯示

  • RGBA 掩碼的順序(wiki 文件裡是 ARGB 的順序)

我們讓 BMP 的畫素佈局和 canvas 保持一致,這樣可無需對現有資料做任何修改。通過 getImageData() 獲取資料,前面加上檔案頭,即可變成一張 BMP 檔案。

演示:https://www.etherdream.com/funnyscript/canvas-to-bmp/

雖然是 BMP 圖片,但和 PNG 一樣同樣支援透明度。

使用這個方案,有時甚至都可以不用 canvas,直接通過演算法在記憶體裡畫出影象,然後轉換成 BMP 進行顯示。