Chupurnov Valeriy
Chupurnov Valeriy
Front End Engineer

Как уменьшить изображение на NodeJS

/blog/uploads/images/1631790283266-image-image.webp

Я уже писал, что встроил в этот блог загрузку картинок через JS.

Но уже написав несколько статей, с ужасом обнаружил, что все картинки, которые были вставлены в статью - просто огромны.

2мб картинка, которая на экране занимает не более 600px. И даже при хорошем интернете, грузится с ощутимыми тормозами.

Так не пойдет. Будем резать картинки на NodeJS а также сжимать их.

Под конечный формат я выбрал webp, так как он дает наибольший профит при сжатии. Вы можете сказать, что его не поддерживает IE, ну и бог с ним =) Я веду этот блог для прогрессивной части человечества. Вам же ничего не мешает конвертировать в более олдскульные форматы: JPG или PNG.

Поехали!

Для начала выберем либу, которая будет резать нам изображение на NodeJS. После недолгих поисков, я нашел вот это чудо: sharp

Библиотека умеет удобное API, и не требует еще каких-то плагинов.

Для начала поставим ее:

npm install sharp

Ну и в месте, где мы загружаем картинку, сразу же ее режем и сжимаем:

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

const 
    uploadsPath = './uploads/images/',		
    filename = path.resolve(uploadsPath, req.file.filename),
    ext = path.extname(filename);

const toFileName = path.resolve(
    uploadsPath,
    path.basename(filename, ext) + '.webp'
);

await sharp(filename)
    .resize({ width: 1000, withoutEnlargement: true })
    .webp({
        quality: 80,
        lossless: false
    })
    .toFile(toFileName);

Про параметры особо не буду, замечу лишь что withoutEnlargement задает режим, когда картинка не увеличивается до размера width, если она больше. lossless можете выставить в true, тогда изображение не будет терять в качестве, но и его размеры будут ужасные.

Ну и метод webp имеет соотвествующие альтернативы для других форматов изображений.

Собственно это все, можете еще опционально удалять исходное изображение. Я решил на всякий случай оставлять оригиналы.

Всем добра, а я пойду резать те картинки, которые уже загрузил до этого!)

Upd. А потом я пушнул все на сервер и все сломалось =)