Sharp для JavaScript (Node.js): полное руководство с примерами

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

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

Начать курс

Введение: Что такое Sharp и зачем она нужна?

Sharp — это высокопроизводительная библиотека для обработки изображений, написанная на C++ и предоставляющая удобный API для Node.js. Она позволяет преобразовывать изображения форматов JPEG, PNG, WebP, AVIF, TIFF и GIF в другие форматы, изменять их размер, обрезать, поворачивать, добавлять эффекты и многое другое.

Основное преимущество Sharp — это скорость. Библиотека использует нативные библиотеки libvips, что делает её в несколько раз быстрее аналогов (например, Jimp или gm). Она идеально подходит для:

  • Веб-серверов и API — динамическая обработка аватарок, превью, оптимизация изображений перед загрузкой.
  • Пакетной обработки — конвертация тысяч изображений в нужный формат и размер.
  • Создания миниатюр и галерей — быстрая генерация thumbnail.
  • Оптимизации веса изображений — сжатие без потери качества (или с контролируемой потерей).

Sharp работает с буферами, потоками (streams) и файлами, что делает её гибкой для интеграции в любые Node.js приложения.

Установка

Установка Sharp выполняется через npm. Для работы библиотеки требуется Node.js версии 12.13.0 или выше (рекомендуется 14+).

npm install sharp

Если вы используете yarn:

yarn add sharp

Важно: Sharp компилирует нативные модули при установке. Если у вас возникают ошибки, убедитесь, что установлены build-essential (на Linux) или Xcode Command Line Tools (на macOS). Для Windows обычно достаточно Visual Studio Build Tools.

После установки импортируйте библиотеку в ваш проект:

const sharp = require('sharp');

Быстрый старт

Давайте напишем простой скрипт, который загружает изображение, уменьшает его до ширины 300 пикселей (сохраняя пропорции) и сохраняет в формате WebP.

const sharp = require('sharp');
const path = require('path');

async function quickStart() {
    try {
        await sharp('input.jpg')
            .resize(300) // Ширина 300px, высота подстроится автоматически
            .webp({ quality: 80 }) // Конвертируем в WebP с качеством 80%
            .toFile('output.webp');
        
        console.log('Изображение успешно обработано!');
    } catch (error) {
        console.error('Ошибка:', error);
    }
}

quickStart();

Этот пример демонстрирует цепочку методов (chaining), которая является основой работы с Sharp. Каждый метод возвращает новый экземпляр Sharp, что позволяет последовательно применять трансформации.

Основные методы и функции

Ниже представлены 10 ключевых методов Sharp с подробным описанием, параметрами и примерами кода.

1. resize() — Изменение размера изображения

Что делает: Изменяет ширину и/или высоту изображения. Может обрезать или вписывать изображение в заданные рамки.

Параметры:

  • width (number, опционально) — новая ширина в пикселях.
  • height (number, опционально) — новая высота в пикселях.
  • options (object, опционально):
    • fit (string) — режим вписывания: 'cover' (заполнить, обрезая лишнее), 'contain' (вписать целиком), 'fill' (растянуть), 'inside' (уменьшить до вписывания), 'outside' (увеличить до выхода за границы). По умолчанию 'cover'.
    • position (string) — позиция при обрезке: 'center', 'top', 'left', 'right', 'bottom' и т.д.
    • withoutEnlargement (boolean) — запретить увеличение изображения.

Пример:

// Уменьшить до 200x200, обрезая по центру
await sharp('input.jpg')
    .resize(200, 200, { fit: 'cover', position: 'center' })
    .toFile('output_200x200.jpg');

// Вписать в прямоугольник 400x300 без растяжения
await sharp('input.jpg')
    .resize(400, 300, { fit: 'inside' })
    .toFile('output_contain.jpg');

2. toFile() — Сохранение результата в файл

Что делает: Записывает обработанное изображение в файл на диске. Это конечный метод в цепочке.

Параметры:

  • fileOut (string) — путь к выходному файлу. Формат определяется по расширению (.jpg, .png, .webp и т.д.).

Пример:

await sharp('input.png')
    .resize(100)
    .toFile('output_thumb.png');

3. toBuffer() — Получение результата в виде буфера

Что делает: Возвращает обработанное изображение как Buffer (бинарные данные). Полезно для отправки через HTTP или сохранения в базу данных.

Параметры: Нет.

Пример:

const buffer = await sharp('input.jpg')
    .resize(150)
    .jpeg({ quality: 70 })
    .toBuffer();

// Теперь buffer можно отправить как ответ сервера
res.type('image/jpeg').send(buffer);

4. jpeg() / png() / webp() / avif() — Настройка выходного формата

Что делает: Задает параметры кодирования для соответствующего формата. Если не вызвать ни один из этих методов, Sharp сохранит в исходном формате (или определит по расширению файла).

Параметры (общие для всех):

  • quality (number, 0-100) — качество сжатия. Для JPEG по умолчанию 80, для WebP — 80.
  • progressive (boolean) — прогрессивный JPEG (только для jpeg).
  • compressionLevel (number, 0-9) — уровень сжатия PNG (по умолчанию 6).
  • lossless (boolean) — сжатие без потерь (для WebP и AVIF).

Пример:

// Сохранить как JPEG с качеством 50%
await sharp('input.png')
    .jpeg({ quality: 50, progressive: true })
    .toFile('output_compressed.jpg');

// Сохранить как WebP без потерь
await sharp('input.jpg')
    .webp({ lossless: true })
    .toFile('output_lossless.webp');

5. rotate() — Поворот изображения

Что делает: Поворачивает изображение на заданный угол. Также автоматически корректирует ориентацию на основе EXIF-данных, если передать true.

Параметры:

  • angle (number, опционально) — угол поворота в градусах (кратный 90). Если не указан, используется EXIF-ориентация.
  • options (object, опционально) — содержит свойство background (string) для цвета фона (по умолчанию черный).

Пример:

// Поворот на 90 градусов по часовой стрелке
await sharp('input.jpg')
    .rotate(90)
    .toFile('rotated_90.jpg');

// Автоматическая коррекция по EXIF
await sharp('input.jpg')
    .rotate()
    .toFile('corrected.jpg');

6. flip() и flop() — Отражение изображения

Что делает: flip() отражает изображение по вертикали (верх-низ). flop() отражает по горизонтали (лево-право).

Параметры: Нет.

Пример:

// Отражение по вертикали
await sharp('input.jpg')
    .flip()
    .toFile('flipped_vertical.jpg');

// Отражение по горизонтали
await sharp('input.jpg')
    .flop()
    .toFile('flopped_horizontal.jpg');

7. grayscale() — Преобразование в оттенки серого

Что делает: Делает изображение черно-белым (оттенки серого).

Параметры: Нет (но можно передать true для явного включения).

Пример:

await sharp('colorful.jpg')
    .grayscale()
    .toFile('black_and_white.jpg');

8. tint() — Тонирование изображения

Что делает: Накладывает цветной оттенок на изображение. Полезно для создания эффектов или цветокоррекции.

Параметры:

  • tint (object) — объект с цветом в формате RGB: { r: number, g: number, b: number }.

Пример:

// Наложить красный оттенок
await sharp('input.jpg')
    .tint({ r: 255, g: 0, b: 0 })
    .toFile('red_tinted.jpg');

9. blur() — Размытие изображения

Что делает: Применяет гауссово размытие к изображению. Полезно для создания эффекта "боке" или размытия фона.

Параметры:

  • sigma (number, опционально) — радиус размытия (стандартное отклонение). По умолчанию 3. Больше значение — сильнее размытие.

Пример:

// Легкое размытие
await sharp('input.jpg')
    .blur(2)
    .toFile('blurred_light.jpg');

// Сильное размытие
await sharp('input.jpg')
    .blur(10)
    .toFile('blurred_heavy.jpg');

10. composite() — Наложение одного изображения на другое

Что делает: Позволяет наложить одно или несколько изображений (watermark, логотип) поверх основного. Поддерживает позиционирование и смешивание.

Параметры:

  • images (array) — массив объектов, каждый из которых содержит:
    • input (string|Buffer) — путь к накладываемому изображению или буфер.
    • top (number) — отступ сверху в пикселях.
    • left (number) — отступ слева в пикселях.
    • blend (string) — режим смешивания: 'over' (поверх), 'in', 'out', 'atop', 'xor' и др.
    • gravity (string) — позиция: 'center', 'north', 'south' и т.д. (альтернатива top/left).

Пример:

// Наложение водяного знака в правый нижний угол
await sharp('background.jpg')
    .composite([
        {
            input: 'logo.png',
            gravity: 'southeast', // Юго-восток (правый нижний угол)
            blend: 'over'
        }
    ])
    .toFile('watermarked.jpg');

Реальный практический пример: Создание миниатюр для галереи

Представьте, что у вас есть веб-приложение, где пользователи загружают фотографии. Вам нужно создать три версии каждого изображения: оригинал (

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