canvas 2 image的使用小心得

只盼雲巔 發表於 2022-05-13

在開發中遇到一個設定透明色的需求,大概描述就是一張圖,然後再給一個顏色,把這個圖片上所有這個顏色的畫素點設定為透明色,如下圖
image.png
實現思路就是將圖片畫到canvas上,然後遍歷圖片畫素資訊,將指定的rgb的alpha設定為0,即設定為全透明。

  const canvas = document.createElement('canvas');
  const context = canvas.getContext('2d');
  const img = new Image();
  img.crossOrigin = 'Anonymous';
  img.src = src;
  img.onload = () => { 
    const w = img.width;
    const h = img.height;
      context.drawImage(img, 0, 0);
    const imgData = context.getImageData(0, 0, w, h);
    const pixcount = w * h;
    for (let i = 0; i < pixcount * 4; i += 4) {
      const r = imgData.data[i];
      const g = imgData.data[i + 1];
      const b = imgData.data[i + 2];
      if (
        Math.abs(r - color.r) <= dis &&
        Math.abs(g - color.g) <= dis &&
        Math.abs(b - color.b) <= dis
      ) {
        imgData.data[i + 3] = 0;
      }
    }
    // 轉成base64
    canvas.toDataURL('image/webp')
}
  

在此功能實現過程中發現幾個問題:
1、canvas.toDataURL(type, encoderOptions)
圖片格式type預設為image/png,
encoderOptions 圖片質量預設0.92 但是此引數在type為image/png時是不生效的,只在
image/jpeg和image/webp格式下生效
2、在使用此方式的過程中發現,原始圖片jpeg只有1M,設定透明色後圖片格式為png時圖片體積增 大到10M🤯🤯,
為了解決此問題,做了以下嘗試:
縮放canvas,匯出仍舊是原canvas大小,圖片還是10M,此方案不行🙅‍♂️
設定為jpeg格式,會丟失透明畫素,透明畫素變成了黑色,當時的我太蠢了jpeg怎麼會有透明畫素呢😅
設定為image/webp格式,圖片體積900K, 完美😊,但是請注意此type在Safari上是不支援,在safari上canvas.toDataURL('image/webp')會預設變成canvas.toDataURL('image/png')