Sharp.js 是一个高性能的 Node.js 图像处理库,它基于 C 语言编写的 libvips 库封装而来,为开发者提供了便捷、高效的图片编辑与转换功能。下面将详细阐述 Sharp.js 的使用方法,结合示例代码与注释,展示其在图像处理中的强大能力。

1. 安装 Sharp.js

首先,通过 npm 安装 Sharp.js:

 

Bash

npm install sharp

注释:

  • 使用 npm install sharp 命令将 Sharp.js 库添加到项目依赖中。

2. 导入 Sharp.js

在需要使用 Sharp.js 的 JavaScript 文件中导入库:

 

Javascript

const sharp = require('sharp');

注释:

  • 通过 require 函数引入 Sharp.js,将其赋值给变量 sharp,以便后续调用库中的方法。

3. 基本操作示例

以下是一些常用的 Sharp.js 操作示例,涵盖图片读取、转换、裁剪、旋转、滤镜应用等:

3.1 读取与保存图片
 

Javascript

sharp('input.jpg')
  .toFile('output.png', (err, info) => {
    if (err) throw err;
    console.log(`Output image saved with size ${info.size}`);
  });

注释:

  • sharp('input.jpg') 创建一个 Sharp 实例,传入图片文件路径作为参数。
  • .toFile('output.png', ...) 将处理后的图片保存到指定路径,这里将原图以 PNG 格式保存。
  • 如果保存过程中发生错误,err 参数会包含相关信息,否则输出保存成功消息及输出文件大小。
3.2 图片格式转换
 

Javascript

sharp('input.jpg')
  .toFormat('webp')
  .toFile('output.webp', (err, info) => {
    if (err) throw err;
    console.log(`Converted to WebP, output image saved with size ${info.size}`);
  });

注释:

  • .toFormat('webp') 指定输出格式为 WebP,将在保存时进行格式转换。
  • 其余部分与上例相同,保存转换后的 WebP 图片并处理错误。
3.3 裁剪图片
 

Javascript

sharp('input.jpg')
  .extract({ left: 100, top: 50, width: 300, height: 200 })
  .toFile('output_cropped.jpg', (err, info) => {
   if (err) throw err;
    console.log(`Cropped image saved with size ${info.size}`);
  });

注释:

  • .extract({ left, top, width, height }) 方法用于裁剪图片,传入裁剪区域的左上角坐标(lefttop)及裁剪尺寸(widthheight)。
  • 其余部分与之前示例相同,保存裁剪后的图片并处理错误。
3.4 旋转图片
 

Javascript

sharp('input.jpg')
  .rotate(90)
  .toFile('output_rotated.jpg', (err, info) => {
    if (err) throw err;
    console.log(`Rotated image saved with size ${info.size}`);
  });

注释:

  • .rotate(angle) 方法用于旋转图片,传入旋转角度(以度为单位)。
  • 其余部分与之前示例相同,保存旋转后的图片并处理错误。
3.5 应用滤镜
 

Javascript

sharp('input.jpg')
  .resize(800, 600) // 先缩放到指定尺寸
  .sharpen() // 应用锐化滤镜
  .blur(10) // 应用模糊滤镜,参数为模糊半径
  .toFile('output_filtered.jpg', (err, info) => {
    if (err) throw err;
    console.log(`Filtered image saved with size ${info.size}`);
  });

注释:

  • .resize(width, height) 缩放图片至指定宽度和高度。
  • .sharpen() 应用锐化滤镜,增强图片边缘对比度。
  • .blur(radius) 应用高斯模糊滤镜,参数为模糊半径。
  • 其余部分与之前示例相同,保存应用滤镜后的图片并处理错误。

4. 流式处理与链式调用

Sharp.js 支持流式处理,可以高效地处理大文件或网络流。同时,其方法调用采用链式结构,使得代码既简洁又直观:

 

Javascript

const http = require('http');
const fs = require('fs');

http.get('http://example.com/large-image.jpg', (response) => {
  response.pipe(
    sharp()
      .resize(800, 600)
      .jpeg({ quality: 80 })
      .toBuffer((err, buffer, info) => {
        if (err) throw err;
        console.log(`Resized & compressed image has size ${info.size}`);
        fs.writeFileSync('output_from_stream.jpg', buffer);
      })
  );
});

注释:

  • 使用 http.get 从远程服务器获取图片资源,返回一个可读流。
  • 将响应流 pipe 到 Sharp 实例,链式调用 .resize.jpeg(指定 JPEG 质量)和 .toBuffer 方法。
  • .toBuffer 将处理后的图片转换为 Buffer,并在回调中接收处理结果。此时可以检查图片大小,并将其写入文件。

5. 并行处理与并发控制

Sharp.js 支持并行处理多个图像,但需要注意资源消耗和并发控制:

 

Javascript

const fs = require('fs');
const path = require('path');
const { promisify } = require('util');
const sharp = require('sharp');

const readdirAsync = promisify(fs.readdir);
const sharpAsync = promisify(sharp().toFile);

async function processImages(directory, outputDir) {
  const files = await readdirAsync(directory);
  const imageFiles = files.filter((file) => /\.(jpg|png)$/i.test(file));

  const resizePromises = imageFiles.map(async (imageFile) => {
    const inputPath = path.join(directory, imageFile);
    const outputPath = path.join(outputDir, `${Date.now()}_${imageFile}`);

    return sharpAsync(inputPath, { width: ½00, height: ⅔00 }, outputPath);
  });

  // 控制并发数,避免资源过度消耗
  const concurrency = 4;
  const processedImages = await Promise.all(
    Array.from({ length: concurrency }, (_, i) =>
      Promise.all(resizePromises.slice(i * concurrency, (i + 1) * concurrency))
    )
  );

  console.log(`Processed ${processedImages.length} images.`);
}

processImages('./input', './output');

注释:

  • 使用异步函数和 Promisify 封装文件操作和 Sharp 方法调用,以实现异步并行处理。
  • processImages 函数接受输入目录和输出目录,读取目录中的图片文件,筛选出 JPG 和 PNG 格式。
  • 创建一个包含每个图片文件处理任务的 Promise 数组 resizePromises
  • 通过 Promise.all 和数组切片控制并发数,避免一次性启动过多处理任务导致资源过度消耗。
  • 最后,等待所有图片处理完成,并输出处理总数。

总结

Sharp.js 提供了一套强大且易用的接口,让 Node.js 开发者能够轻松处理各种图像编辑与转换任务。通过链式调用,可以实现图片读取、格式转换、裁剪、旋转、滤镜应用等功能。同时,Sharp.js 支持流式处理和并行处理,使得处理大量或大尺寸图片时仍能保持高效。在使用过程中,注意合理控制并发以避免资源过度消耗。

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐