無需webpack,使用 Node.js 壓縮本地圖片:sharp 與 imagemin 的對比與應用

在現代 web 開發中,優化圖片大小是提升網站性能的關鍵步驟之一。本文將介紹如何使用 Node.js 庫 sharp 和 imagemin 壓縮本地圖片,並對這兩種工具的功能和壓縮能力進行詳細對比。

sharp 的使用

安裝 sharp

首先,通過 npm 安裝 sharp:

Terminal window
1
npm install sharp

使用 sharp 進行圖片處理

sharp 是一個高性能的圖片處理庫,支持多種圖片操作。以下是一些常見的用法:

  1. 調整大小 (Resize)

    1
    const sharp = require("sharp");
    2
    3
    sharp("input.jpg")
    4
    .resize(300, 200) // 300px 寬,200px 高
    5
    .toFile("output.jpg", (err, info) => {
    6
    if (err) {
    7
    console.error(err);
    8
    } else {
    9
    console.log(info);
    10
    }
    11
    });
  2. 裁剪 (Crop)

    1
    sharp("input.jpg")
    2
    .resize(300, 300, {
    3
    fit: sharp.fit.cover,
    4
    position: sharp.strategy.entropy,
    5
    })
    6
    .toFile("output.jpg", (err, info) => {
    7
    if (err) {
    8
    console.error(err);
    9
    } else {
    10
    console.log(info);
    11
    }
    12
    });
  3. 旋轉 (Rotate)

    1
    sharp("input.jpg")
    2
    .rotate(90) // 順時針旋轉90度
    3
    .toFile("output.jpg", (err, info) => {
    4
    if (err) {
    5
    console.error(err);
    6
    } else {
    7
    console.log(info);
    8
    }
    9
    });
  4. 添加水印 (Composite)

    1
    sharp("input.jpg")
    2
    .composite([{ input: "watermark.png", gravity: "southeast" }])
    3
    .toFile("output.jpg", (err, info) => {
    4
    if (err) {
    5
    console.error(err);
    6
    } else {
    7
    console.log(info);
    8
    }
    9
    });
  5. 壓縮目錄下的所有圖片

    1
    const sharp = require("sharp");
    2
    const fs = require("fs");
    3
    const path = require("path");
    4
    5
    const inputDir = "path/to/your/images";
    6
    const outputDir = "path/to/output/images";
    7
    8
    fs.readdir(inputDir, (err, files) => {
    9
    if (err) {
    10
    console.error("Error reading input directory:", err);
    11
    return;
    12
    }
    13
    14
    files.forEach((file) => {
    15
    const inputFile = path.join(inputDir, file);
    16
    const outputFile = path.join(outputDir, file);
    17
    18
    sharp(inputFile)
    19
    .resize(800)
    20
    .toFormat("jpeg", { quality: 80 })
    21
    .toFile(outputFile, (err, info) => {
    22
    if (err) {
    23
    console.error("Error processing file:", err);
    24
    } else {
    25
    console.log("File processed:", info);
    26
    }
    27
    });
    28
    });
    29
    });

imagemin 的使用

安裝 imagemin

首先,通過 npm 安裝 imagemin 及其相關插件:

Terminal window
1
npm install imagemin imagemin-mozjpeg imagemin-pngquant imagemin-svgo

使用 imagemin 進行圖片壓縮

imagemin 是一個高度可配置的圖片壓縮庫,支持多種插件。由於 imagemin 是一個 ES 模塊,因此我們不能使用 require 來引入它,我們需要在 package.json 中添加如下代碼來開啟ES Module:

1
"type": "module",

以下是一些常見的imagemin用法:

  1. 壓縮 JPEG

    1
    import imagemin from "imagemin";
    2
    import imageminMozjpeg from "imagemin-mozjpeg";
    3
    4
    (async () => {
    5
    await imagemin(["images/*.jpg"], {
    6
    destination: "output",
    7
    plugins: [imageminMozjpeg({ quality: 70 })],
    8
    });
    9
    })();
  2. 壓縮 PNG

    1
    import imagemin from "imagemin";
    2
    import imageminPngquant from "imagemin-pngquant";
    3
    4
    (async () => {
    5
    await imagemin(["images/*.png"], {
    6
    destination: "output",
    7
    plugins: [
    8
    imageminPngquant({
    9
    quality: [0.6, 0.8],
    10
    }),
    11
    ],
    12
    });
    13
    })();
  3. 壓縮 SVG

    1
    import imagemin from "imagemin";
    2
    import imageminSvgo from "imagemin-svgo";
    3
    4
    (async () => {
    5
    await imagemin(["images/*.svg"], {
    6
    destination: "output",
    7
    plugins: [imageminSvgo()],
    8
    });
    9
    })();
  4. 壓縮 GIF

    1
    import imagemin from "imagemin";
    2
    import imageminGifsicle from "imagemin-gifsicle";
    3
    4
    (async () => {
    5
    await imagemin(["images/*.gif"], {
    6
    destination: "output",
    7
    plugins: [imageminGifsicle({ optimizationLevel: 3 })],
    8
    });
    9
    })();
  5. 壓縮目錄下的所有圖片

    1
    import imagemin from "imagemin";
    2
    import imageminMozjpeg from "imagemin-mozjpeg";
    3
    import imageminPngquant from "imagemin-pngquant";
    4
    import imageminSvgo from "imagemin-svgo";
    5
    import path from "path";
    6
    7
    const inputDir = "path/to/your/images/*.{jpg,png,svg}";
    8
    const outputDir = "path/to/output/images";
    9
    10
    (async () => {
    11
    const files = await imagemin([inputDir], {
    12
    destination: outputDir,
    13
    plugins: [
    14
    imageminMozjpeg({ quality: 80 }),
    15
    imageminPngquant({
    16
    quality: [0.6, 0.8],
    17
    }),
    18
    imageminSvgo(),
    19
    ],
    20
    });
    21
    console.log("Images optimized:", files);
    22
    })();

sharp 與 imagemin 的對比

壓縮效率

  • sharp 使用 libvips 庫,壓縮速度非常快,尤其是在處理大批量圖片時表現優異。
  • imagemin 依賴於具體的插件,不同的插件壓縮效率有所不同。總體來說,imagemin 的壓縮速度稍慢於 sharp,但提供了更多格式的支持。

壓縮質量

  • sharp 提供了高質量的壓縮效果,支持調整壓縮質量和圖片大小,可以在保持較好圖片質量的同時顯著減少文件大小。
  • imagemin 提供了多個插件,用戶可以根據需要選擇不同的插件來優化不同格式的圖片。其壓縮質量也非常高,尤其是在使用特定的優化插件時(如 imagemin-mozjpeg)。

功能性

  • sharp 不僅僅是一個壓縮工具,它還提供了強大的圖片處理功能,如裁剪、旋轉、調整大小、水印等。
  • imagemin 專注於圖片壓縮,通過不同的插件支持多種圖片格式的優化,但不具備圖片處理的其他功能。

結論

總結來說,如果需要高效的圖片處理和壓縮功能,sharp 是一個非常不錯的選擇。如果需要優化多種圖片格式且專注於壓縮效果,imagemin 是更好的選擇。