Работа с изображениями в Node.js: библиотека Sharp

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Библиотека Sharp для работы с изображениями в Node.js

В современной веб-разработке обработка изображений на серверной стороне является критически важной задачей. Node.js, благодаря своей событийно-ориентированной архитектуре, отлично справляется с этой задачей. Среди множества библиотек для работы с изображениями особое место занимает Sharp — высокопроизводительный модуль с открытым исходным кодом, написанный на C++ и использующий библиотеку libvips.

Что такое Sharp?

Sharp — это Node.js модуль для быстрой обработки изображений. Он поддерживает форматы JPEG, PNG, WebP, AVIF, TIFF и GIF. Основные возможности включают изменение размера, обрезку, поворот, коррекцию цвета, наложение водяных знаков и конвертацию между форматами. Благодаря использованию libvips, Sharp работает в 4-5 раз быстрее, чем аналогичные библиотеки (например, ImageMagick или GraphicsMagick).

Установка

Установка производится через npm. Убедитесь, что в системе установлены компиляторы C++ (gcc или clang) и libvips (на некоторых ОС требуется предварительная установка).

npm install sharp

После установки вы можете импортировать модуль в ваш проект:

const sharp = require('sharp');

Основные операции с изображениями

1. Изменение размера (resize)

Самая частая задача — уменьшить или увеличить изображение. Sharp позволяет задать ширину, высоту или обе величины одновременно. Если указать только один параметр, второй будет вычислен пропорционально.

const sharp = require('sharp');

async function resizeImage() {
  try {
    await sharp('input.jpg')
      .resize(300, 200) // ширина 300px, высота 200px
      .toFile('output-resized.jpg');
    console.log('Изображение изменено');
  } catch (error) {
    console.error('Ошибка:', error);
  }
}

resizeImage();

Для сохранения пропорций используйте fit:

const sharp = require('sharp');

async function resizeWithFit() {
  await sharp('input.jpg')
    .resize({
      width: 300,
      height: 200,
      fit: 'inside' // 'cover', 'contain', 'fill', 'inside', 'outside'
    })
    .toFile('output-fit.jpg');
}

resizeWithFit();

2. Обрезка (crop)

Обрезка позволяет удалить ненужные части изображения. Sharp поддерживает обрезку по заданным координатам или по стратегии (например, центральная обрезка).

const sharp = require('sharp');

async function cropImage() {
  await sharp('input.jpg')
    .extract({ left: 100, top: 50, width: 400, height: 300 })
    .toFile('output-cropped.jpg');
}

cropImage();

Также можно использовать resize с опцией crop:

const sharp = require('sharp');

async function cropWithResize() {
  await sharp('input.jpg')
    .resize(200, 200, { fit: 'cover', position: 'centre' })
    .toFile('output-cover.jpg');
}

cropWithResize();

3. Конвертация форматов

Sharp позволяет легко конвертировать изображения из одного формата в другой. Просто укажите расширение в выходном файле или используйте метод .toFormat().

const sharp = require('sharp');

async function convertToWebP() {
  await sharp('input.png')
    .toFormat('webp')
    .toFile('output.webp');
}

async function convertToJpeg() {
  await sharp('input.webp')
    .jpeg({ quality: 80 })
    .toFile('output.jpg');
}

convertToWebP();
convertToJpeg();

4. Работа с метаданными

Вы можете извлечь метаданные изображения: размеры, цветовое пространство, DPI, EXIF-данные и т.д.

const sharp = require('sharp');

async function getMetadata() {
  const metadata = await sharp('input.jpg').metadata();
  console.log('Метаданные:', metadata);
  // { format: 'jpeg', width: 1920, height: 1080, space: 'srgb', ... }
}

getMetadata();

5. Наложение водяных знаков (composite)

Sharp поддерживает наложение одного изображения на другое, что полезно для добавления водяных знаков.

const sharp = require('sharp');

async function addWatermark() {
  await sharp('input.jpg')
    .composite([
      {
        input: 'watermark.png',
        top: 10,
        left: 10,
        blend: 'over' // 'over', 'in', 'out', 'atop', 'dest', 'xor'
      }
    ])
    .toFile('output-watermarked.jpg');
}

addWatermark();

6. Работа с буферами и потоками

Sharp отлично работает с буфера

Рекомендаций