[Typescript]將HEIF檔轉為JPEG檔

[Typescript]將HEIF檔轉為JPEG檔

Apple在iOS11後,拍照的格式會預設為heif格式檔,導致手機拍照的相片無法直接顯示在網頁上,

於是在Github找到libheif-js套件來處理,首先透過npm安裝起來

npm install libheif-js

接著處理檔案轉換

import libheif from 'libheif-js';


heicConvertToJpeg(): Promise<Blob> {
  return new Promise((resolve, reject) => {
    try {
      const decoder = new libheif.HeifDecoder();
      const imagesArr = decoder.decode(buffer);
      const primaryImage =
        imagesArr.find(x => x.is_primary()) || imagesArr[0];
      const w = primaryImage.get_width();
      const h = primaryImage.get_height();
      const canvas = document.createElement("canvas");
      canvas.width = w;
      canvas.height = h;
      const ctx = canvas.getContext("2d");
      const whiteImage = ctx.createImageData(w, h);
      for (let i = 0; i < w * h; i++) {
        whiteImage.data[i * 4 + 3] = 255;
      }
      primaryImage.display(whiteImage, display_image_data => {
        ctx.putImageData(display_image_data, 0, 0);
        let quality = 24 / 32; //canvas default bit depth (color depth) is 32, shrink to 24

        canvas.toBlob((blob) => {
          canvas.remove();
          resolve(blob);
        }, 'image/jpeg', quality);
      });
    }
    catch (e) {
      reject(e);
    }
  });
}

測試時,又遇到以下訊息

查了一下Stack Overflow,可在package.json中加入以下這段即可

"browser": {
  "fs": false,
  "crypto": false,
  "path": false
}

(原理不大清楚,不過目前來說是有用的解法)

如此就可以將heif檔轉成jpg檔後,呈現在網頁上,

如果要轉成png檔,則把image/jpeg改為image/png即可。

當然也可以要求使用者修改手機上設定(參考Apple支援服務),不過這種事不見得每個人都願意做,所以還是順手轉一下比較快。

參考資料

[Github] libheif-js

[Github] heic2any

什麼是 HEIF/HEIC 照片格式?

[Stack Overflow] Angular 6 many Can't resolve errors (crypto, fs, http, https, net, path, stream, tls, zlib)

Canvas 教學文件