Compress Local Images Using Node.js Without Webpack: Comparison and Application of sharp and imagemin

In modern web development, optimizing image size is a key step to enhance website performance. This article will introduce how to compress local images using Node.js libraries sharp and imagemin, and provide a detailed comparison of their functions and compression capabilities.

Using sharp

Installing sharp

First, install sharp via npm:

Terminal window
1
npm install sharp

Image Processing with sharp

sharp is a high-performance image processing library that supports various image operations. Here are some common usages:

  1. Resize:

    1
    const sharp = require("sharp");
    2
    3
    sharp("input.jpg")
    4
    .resize(300, 200) // 300px width, 200px height
    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) // Rotate 90 degrees clockwise
    3
    .toFile("output.jpg", (err, info) => {
    4
    if (err) {
    5
    console.error(err);
    6
    } else {
    7
    console.log(info);
    8
    }
    9
    });
  4. Add Watermark (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. Compress All Images in a Directory:

    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) // Resize to width 800px, height will be auto-scaled to maintain aspect ratio
    20
    .toFormat("jpeg", { quality: 80 }) // Convert to JPEG with quality of 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
    });

Using imagemin

Installing imagemin

First, install imagemin and its related plugins via npm:

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

Compressing Images with imagemin

imagemin is a highly configurable image compression library that supports various plugins. Since imagemin is an ES module, we cannot use require to import it. We need to add the following code to package.json to enable ES Module:

1
"type": "module",

Here are some common usages of imagemin:

  1. Compress 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. Compress 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. Compress 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. Compress 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. Compress All Images in a Directory:

    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
    })();

Comparison of sharp and imagemin

Compression Efficiency

  • sharp uses the libvips library and offers very fast compression, especially when processing large batches of images.
  • imagemin relies on specific plugins, and the compression efficiency varies. Overall, imagemin is slightly slower than sharp, but it provides support for more formats.

Compression Quality

  • sharp offers high-quality compression, allowing adjustments to compression quality and image size, significantly reducing file size while maintaining good image quality.
  • imagemin offers multiple plugins, allowing users to choose different plugins for optimizing various image formats. Its compression quality is also very high, especially when using specific optimization plugins like imagemin-mozjpeg.

Functionality

  • sharp is not just a compression tool; it also provides powerful image processing functions such as cropping, rotating, resizing, watermarking, etc.
  • imagemin focuses on image compression, supporting optimization for various image formats through different plugins, but lacks other image processing capabilities.

Conclusion

In summary, if you need efficient image processing and compression, sharp is a very good choice. If you need to optimize multiple image formats and focus on compression effects, imagemin is the better choice.