Обработка изображений в Node.js: resize, crop с Sharp и Jimp

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

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

Начать курс

Работа с изображениями в Node.js: resize и crop

В современной веб-разработке часто возникает необходимость обрабатывать изображения на серверной стороне: изменять размер, обрезать, конвертировать форматы. Node.js предлагает несколько мощных библиотек для этих задач. В этой статье мы разберём две самые популярные — Sharp (высокая производительность, основана на libvips) и Jimp (чистый JavaScript, не требует нативных зависимостей).

1. Установка и подготовка

Для начала создайте новый проект и установите одну из библиотек:

mkdir image-processor && cd image-processor
npm init -y
npm install sharp jimp

2. Изменение размера (resize) с Sharp

Sharp — это быстрая библиотека на C, которая отлично подходит для production. Она поддерживает потоковую обработку и автоматическое определение формата.

const sharp = require('sharp');

// Простой resize до ширины 300px (высота сохраняет пропорции)
sharp('input.jpg')
  .resize(300)
  .toFile('output-300.jpg')
  .then(() => console.log('Готово!'))
  .catch(err => console.error(err));

// Принудительный resize до точных размеров 200x200 (с искажением)
sharp('input.jpg')
  .resize(200, 200, { fit: 'fill' })
  .toFile('output-fill.jpg');

// Умный resize с сохранением пропорций (обрезка по центру)
sharp('input.jpg')
  .resize(200, 200, { fit: 'cover', position: 'centre' })
  .toFile('output-cover.jpg');

3. Обрезка (crop) с Sharp

Метод extract позволяет вырезать прямоугольную область изображения.

const sharp = require('sharp');

// Вырезаем область: left=100, top=50, width=400, height=300
sharp('input.jpg')
  .extract({ left: 100, top: 50, width: 400, height: 300 })
  .toFile('cropped.jpg')
  .then(info => console.log('Обрезано:', info));

4. Работа с Jimp (чистый JavaScript)

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

const Jimp = require('jimp');

// resize до ширины 300px
Jimp.read('input.jpg')
  .then(image => {
    return image
      .resize(300, Jimp.AUTO) // AUTO сохраняет пропорции
      .writeAsync('output-jimp.jpg');
  })
  .then(() => console.log('Jimp resize готов'))
  .catch(err => console.error(err));

// crop (обрезка) с координатами
Jimp.read('input.jpg')
  .then(image => {
    return image
      .crop(100, 50, 400, 300) // x, y, width, height
      .writeAsync('cropped-jimp.jpg');
  })
  .catch(err => console.error(err));

5. Комбинированный пример: resize + crop за один проход

Часто требуется сначала обрезать, а потом уменьшить. Sharp делает это эффективно благодаря внутреннему конвейеру:

const sharp = require('sharp');

sharp('input.jpg')
  .extract({ left: 50, top: 30, width: 800, height: 600 })
  .resize(400, 300, { fit: 'cover' })
  .toFile('result.jpg')
  .then(info => console.log('Итоговый размер:', info.width, 'x', info.height));

6. Сравнение Sharp vs Jimp

  • Производительность: Sharp в 5-10 раз быстрее для больших файлов.
  • Установка: Jimp не требует нативных зависимостей (просто npm install).
  • Функции: Sharp поддерживает больше форматов (heif, tiff, avif) и продвинутые фильтры.
  • Потоковая обработка: Sharp работает с потоками Node.js (pipe), Jimp — только с буферами.
  • Рекомендация: Для высоконагруженных сервисов выбирайте Sharp. Для простых скриптов или учебных проектов — Jimp.

7. Работа с буфером (без сохранения в файл)

Часто изображения приходят через HTTP или хранятся в памяти. Обе библиотеки поддерживают работу с Buffer:

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

// Читаем файл в буфер
const inputBuffer = fs.readFileSync('input.jpg');

// Обрабатываем в памяти
sharp(inputBuffer)
  .resize(150, 150)
  .toBuffer()
  .then(outputBuffer => {
    // Отправляем buffer клиенту или сохраняем
    fs.writeFileSync('thumb.jpg', outputBuffer);
  });

8. Обработка ошибок и валидация

Всегда проверяйте, что файл существует и является изображением:

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