Contents

使用 Sharp 在 Node.js 中壓縮圖片

不必要的大圖像可能會導致回應時間變慢,消耗過多的頻寬,並為使用者(尤其是連線速度較慢的使用者)提供緩慢的體驗。這可能會導致更高的跳出率或更少的轉換。

在傳輸數位媒體檔案之前,壓縮其視覺組件可能有助於減輕潛在的複雜性並提供改進的使用者介面。在這方面,夏普模組為實現這一目標提供了一個簡單而便捷的解決方案。

設定您的開發環境

為了說明縮小視覺內容大小的過程,首先使用 Multer 實作檔案上傳功能。人們可以透過複製此 GitHub 儲存庫中的程式碼來加快這一過程。

若要從複製的 GitHub 儲存庫成功設定映像上傳服務,請執行以下命令來安裝任何必要的依賴項:

 npm install

接下來,透過執行以下命令安裝 Sharp:

 npm install sharp

Sharp 模組是用於處理和操作影像的高效能 Node.js 函式庫。您可以使用 Sharp 對影像有效地調整大小、裁剪、旋轉以及執行各種其他操作。 Sharp 對壓縮影像也有出色的支援。

不同影像格式的壓縮技術

不同的圖像格式採用獨特的壓縮策略,因為它們是為解決特定用例和考慮因素而量身定制的,例如品質、檔案尺寸以及透明度和動畫功能等屬性。

JPG/JPEG

JPEG,即聯合影像專家小組的影像壓縮標準,專門用於壓縮具有連續色調和顏色漸變的照片和其他影像。它利用獨特的有損壓縮形式,透過選擇性地丟棄原始影像資料的某些方面來有效地減少檔案大小。

首先導入Sharp模組;其次,提供影像檔案的路徑或包含其內容的緩衝區;第三,使用導入的 Sharp 實例中的.jpeg 方法;最後,包含一個配置對象,其「quality」屬性設定為0 到100 範圍內的數值,其中較低的值表示較小的文件,但視覺品質較差,而較高的值會產生較大的文件,且清晰度較高。

可以根據自己的具體要求調整參數。為了獲得最佳的壓縮性能,建議將該值保持在50-80的範圍內,從而在檔案大小和影像保真度之間達到適當的平衡。

最後,使用“.toFile”方法將壓縮表示儲存在檔案系統中,並將所需輸出檔案的路徑作為參數傳遞。

例如:

 await sharp(req.file.path)
        .jpeg({ quality: 60 })
        .toFile(`./images/compressed-${req.file.filename}`)
        .then(() => {
          console.log(`Compressed ${req.file.filename} successfully`);
        });

影像品質的標準設定預設為 80。

PNG

PNG(即便攜式網路圖形)是一種廣泛認可的圖像檔案格式,以其提供無損資料壓縮的能力而聞名,同時也支援影像透明度,使其具有高度通用性,非常適合各種應用程式。

當嘗試使用 Sharp 壓縮以可移植網絡圖形 (PNG) 格式保存的圖像時,需要注意的是,該過程與壓縮保存為聯合圖像專家組 (JPEG) 文件的類似圖像有一些相似之處。儘管如此,在此過程中必須進行兩項獨特的調整。

Sharp 處理影像的方式是使用 PNG 檔案格式(而不是 JPEG)。

PNG 格式採用了一種新穎的壓縮方法,利用「compressionLevel」參數而不是傳統的「品質」設置,作為控制所實現的壓縮等級的手段。在最低設定 (0) 下,演算法會最快、最廣泛地減少檔案大小,而在最高設定 (9) 下,會產生最慢且最不顯著的壓縮。

例如:

 await sharp(req.file.path)
        .png({
          compressionLevel: 5,
        })
        .toFile(`./images/compressed-${req.file.filename}`)
        .then(() => {
          console.log(`Compressed ${req.file.filename} successfully`);
        });

預設情況下,指派給壓縮等級的值設定為 6。

其他格式

Sharps 也支援以各種其他檔案格式壓縮影像,包括:

將 WebP 圖片壓縮演算法與 Sharp 結合使用遵循與使用 JPEG 類似的過程,唯一的區別是需要從 Sharp 實例呼叫「webp」方法而不是「.jpeg」方法。

Sharp 實作中用於壓縮影像的標記影像檔案格式 (TIFF) 遵循與 JPEG 類似的過程,儘管使用了替代方法呼叫。必須呼叫“tiff”方法,而不是在 Sharp 實例上呼叫“.jpeg”方法。

AVID 格式屬於 Sharp 影像壓縮中使用的 AV1 影像檔案格式,其操作方式與 JPEG 類似。但是,必須在 Sharp 實例上使用 avif 方法,而不是使用.jpeg 方法。此外,值得注意的是 AVIF 格式中品質設定的預設值設定為 50。

HEIF 代表高效率影像檔案格式,與 JPEG 相比,它在壓縮方面採用類似的流程。但是,它需要在 Sharp 實例上使用“heif”方法而不是“.jpeg”方法。此外,預設情況下,AVIF 的影像品質設定為 50。

使用 Sharp 壓縮影像

如果已經複製了 GitHub 儲存庫,則需要存取專案內的「app.js」檔案並將上述導入語句合併到其中。

 const sharp = require("sharp");
const { exec } = require("child_process");

透過「child_process」模組提供的「exec」函數允許在 Node.js 應用程式中執行 shell 命令或外部進程。

此功能可讓您執行比較檔案壓縮之前和之後的尺寸的命令。

接下來,我們將透過將提供的程式碼片段合併到目前的 POST'/single' 處理程序中來取代它。

 app.post("/upload-and-compress", upload.single("image"), async (req, res) => {
  try {
    if (!req.file) {
      return res.status(404).send("Please upload a valid image");
    }

    const compressedFileName = req.file.filename.split(".")[0];
    const compressedImageFilePath = `./images/${compressedFileName}-compressed.png`;

    await sharp(req.file.path)
      .jpeg({ quality: 50 })
      .toFile(compressedImageFilePath)
      .then(() => {
        let sizeBeforeCompression, sizeAfterCompression;
        const sizeBeforeCompressionCommand = `du -h ${req.file.path}`;
        const sizeAfterCompressionCommand = `du -h ${compressedImageFilePath}`;

        exec(sizeBeforeCompressionCommand, (err, stdout, stderr) => {
          sizeBeforeCompression = stdout.split("\\t")[0];

          exec(sizeAfterCompressionCommand, (err, stdout, stderr) => {
            sizeAfterCompression = stdout.split("\\t")[0];

            res.send({
              message: "Image uploaded and compressed successfully",
              sizeBeforeCompression,
              sizeAfterCompression,
            });
          });
        });
      });
  } catch (error) {
    console.log(error);
  }
});

上述程式碼實作包含一種壓縮 JPEG 影像檔案的方法,同時在使用「du」命令之前和之後對它們各自的檔案大小進行比較。

du 命令是一個 Unix 實用程序,它透過估計指定目錄中的檔案和目錄佔用的空間量來提供有關磁碟使用情況的資訊。透過利用「-h」標誌,輸出可以以人類容易理解的格式顯示,指示各個子目錄使用的檔案空間及其各自的內容。

若要啟動檔案傳輸服務的操作,請執行下列指令:

 node app.js

為了驗證應用程式的功能,您可以利用 Postman 用戶端應用程式或您選擇的任何替代 API 測試工具將 JPEG 影像傳送到指定端點「」以進行進一步處理和壓縮。

預計您將收到類似以下格式的回覆:

 {
  "message": "Image uploaded and compressed successfully",
  "sizeBeforeCompression": "13M",
  "sizeAfterCompression": "3.1M"
}

Sharp 模組的其他用途

Sharp 模組提供了全面的影像處理功能,而不僅僅是壓縮。其中包括根據指定尺寸調整影像大小、裁剪、旋轉和翻轉影像。此外,它還支援色彩空間修改、Alpha 通道操作以及不同檔案格式之間的轉換。