Я разрабатываю веб-приложение на Node.js (+ express 4), где пользователи могут установить изображение своего профиля, загрузив его на сервер. Мы уже ограничили mimetype файла и максимальный размер файла, поэтому пользователь не может загружать более 200 КБ изображений в формате PNG или JPEG.
Проблема в том, что мы хотели бы изменить размер (на стороне сервера) загруженного изображения до 200x200, чтобы улучшить загрузку страницы и сэкономить место на диске. После некоторого исследования все ответы указали на использование любого модуля на основе ImageMagick или GraphicsMagick.
Однако необходимость установки ImageMagick / GraphicsMagick для простого изменения размера изображения кажется мне слишком излишней, поэтому есть ли другое решение, кроме этого, для Node.js?
Изменить: я изменил принятое решение на острое, поскольку предыдущее решение (lwip) больше не поддерживается. Спасибо за все ваши отзывы!
источник
Ответы:
Я бы проголосовал за острое :
sharp('input.jpg') .resize(200, 200) .toFile('ouput.jpg', function(err) { // output.jpg is a 200 pixels wide and 200 pixels high image // containing a scaled and cropped version of input.jpg });
Это быстро, обычно в 6 раз быстрее, чем самые быстрые привязки узлов на основе imagemagick , и работает с очень небольшим объемом памяти, возможно, в 10 раз меньше . четкие ссылки на библиотеку изображений libvips напрямую, нет необходимости использовать внешнюю программу, а сама библиотека быстрее и эффективнее, чем * magick в этой задаче. Он поддерживает такие полезные вещи, как поток, буфер и ввод и вывод файловой системы, управление цветом, прозрачность, обещания, наложения, WebP, SVG и многое другое.
Начиная с версии Sharp 0.20, npm будет автоматически загружать полные предварительно скомпилированные двоичные файлы на большинстве платформ, поэтому в node-gyp нет необходимости. Просто введите:
или же:
И вперед.
источник
sharp
больше не имеет внешних зависимостей времени выполнения для пользователей Linux и Windows, так как в него входит предварительно скомпилированная версия libvips. Вы обнаружите, что операции изменения размера примерно в 10 раз быстрее, чем LWIP, и занимают лишь часть памяти.npm install --global --production windows-build-tools
сначала попробуйте запустить . См. Также github.com/Microsoft/nodejs-guidelines/blob/master/…Недавно я начал разрабатывать модуль обработки изображений для NodeJS без каких-либо зависимостей во время выполнения ( прочтите, почему ). Это все еще на ранней стадии, но уже можно использовать.
То, что вы просите, будет сделано следующим образом:
image.resize(200, 200, function(err, image){ // encode resized image to jpeg and get a Buffer object image.toBuffer('jpg', function(err, buffer){ // save buffer to disk / send over network / etc. }); });
Дополнительная информация в репозитории Github модуля .
источник
writeFile
с1.8Mb
изображением, и это требует 130MB памяти. После этого я4MB, 11000x6000
провожу тест, изменяя размер изображения до нескольких миниатюр (640 560 480, ..., 160), и это занимает примерно 1,7 ГБ памяти. Это ошибка?Взгляните на lwip: https://github.com/EyalAr/lwip
Очень просто и удобно
а затем в коде вашего узла
// obtain an image object: require('lwip').open('image.jpg', function(err, image){ // check err... // define a batch of manipulations and save to disk as JPEG: image.batch() .scale(0.75) // scale to 75% .rotate(45, 'white') // rotate 45degs clockwise (white fill) .crop(200) // crop a 200X200 square from center .blur(5) // Gaussian blur with SD=5 .writeFile('output.jpg', function(err){ // check err... // done. }); });
Я успешно реализовал это в моем загрузчике файлов, и он работает как шарм.
источник
Существует хорошая библиотека для работы с изображениями, полностью написанная на JavaScript, без зависимостей от других библиотек, Jimp. https://github.com/oliver-moran/jimp
Пример использования:
var Jimp = require("jimp"); // open a file called "lenna.png" Jimp.read("lenna.png", function (err, lenna) { if (err) throw err; lenna.resize(256, 256) // resize .quality(60) // set JPEG quality .write("lena-small.jpg"); // save });
источник
Sharp в последнее время пользуется некоторой популярностью, но это та же идея, что и привязки * Magick.
Изменение размера изображения совсем не простое. Формат JPEG особенно сложен, и есть несколько способов масштабирования графики с результатами разного качества, некоторые из них легко реализовать. Для этой работы существуют библиотеки обработки изображений, поэтому, если нет другой причины, по которой вы не можете их установить, сделайте это.
источник
Canvas в 2,3 раза быстрее ImageMagic.
Вы можете попробовать сравнить модули Node.js для обработки изображений - https://github.com/ivanoff/images-manipulation-performance
author's results: sharp.js : 9.501 img/sec; minFreeMem: 929Mb canvas.js : 8.246 img/sec; minFreeMem: 578Mb gm.js : 4.433 img/sec; minFreeMem: 791Mb gm-imagemagic.js : 3.654 img/sec; minFreeMem: 804Mb lwip.js : 1.203 img/sec; minFreeMem: 54Mb jimp.js : 0.445 img/sec; minFreeMem: 82Mb
источник
Если вам не нужно большое изображение, вы можете изменить его размер на стороне клиента перед загрузкой:
Чтение файлов в JavaScript с использованием файловых API
Изменение размера изображения на стороне клиента с помощью javascript перед загрузкой на сервер
Многие пользователи могут хорошо представить себя со смартфона, и многие из них имеют размер более 200 КБ. Обратите внимание, что данным, предоставленным клиентом, нельзя доверять, поэтому проверки на стороне сервера по-прежнему применяются.
источник
Я использовал lwip (как ранее предлагал arvind), но переключился на png- обрезку . У меня вроде работает чуть шустрее (Win 8.1 x64, Node v0.12.7). Код в репозитории выглядит невероятно легковесным и прост в использовании.
var pngcrop = require('png-crop'); var config = {left: 10, top: 100, height: 150, width: 150}; pngcrop.crop('cats.png','cats-cropped.png',config);
Конечно, он работает только с файлами png ...
источник
Sharp работает очень хорошо и прост в использовании с потоками, работает как шарм, но вам нужно скомпилировать его с версией node, это его обратная сторона. Я использовал Sharp для обработки изображений с изображением из ведра AWS S3 и работал отлично, но мне пришлось использовать другой модуль. GM не работал у меня, но Jimp работал очень хорошо!
Вы должны обратить внимание на путь написанного изображения, это может дать вам некоторые ошибки, если вы начнете путь с "/".
Вот как я использовал Jimp в nodeJS:
const imageUrl = `SOME_URL`; let imgExported = 'EXPORTED_PIC.png'; Jimp.read(imageUrl) .then(image => { image .resize(X, Y) .write(`tmp/`+ imgExported, err => { if(err) console.error('Write error: ', err); else { ... // don't forget to put a callback() } } });
Также следите за порядком выполнения, поставьте обратный вызов, чтобы другие вещи не происходили, когда вы этого не хотите. Пытался использовать "await" для Jimp.read (), но это не помогло.
источник
Вы можете сделать это с помощью jimp (node_module)
Локальная запись:
Jimp.read(path) // this can be url or local location .then(image=> { image .resize(size, Jimp.AUTO) // jimp.AUTO automatically sets the width so that the image doesnot looks odd .write('path-to-save'); }) .catch(err => { console.log(err); });
Для загрузки на s3 или где угодно.
Jimp.read(urls) // this can be url or local location .then(image=> { image .resize(size, Jimp.AUTO) // jimp.AUTO automatically sets the width so that the image doesnot looks odd .getBase64(Jimp.AUTO, (err, res) => { const buf = new Buffer( res.replace(/^data:image\/\w+;base64,/, ""), "base64" ); var data = { Key: key, Bucket: bucket, Body: body, ContentEncoding: "base64", ContentType: "image/jpeg" }; s3.putObject(data, function(err, data) { if (err) { throw err; } else { console.log("succesfully uploaded the image!"); } }); }); }) .catch(err => { console.log(err); });
источник
Мне нравится библиотека resize-img за ее простоту.
const fs = require('fs'); const resizeImg = require('resize-img'); (async () => { const image = fs.readFileSync('unicorn.png'); const newImage = await resizeImg(image, { width: 128, height: 128 }); fs.writeFileSync('unicorn-128x128.png', newImage); })();
источник
Реализовано изменение размера изображения с помощью Google Drive API v3 . Этот метод рекомендуется для скрипта Google Apps для вставки изображений в Google Таблицы.
Алгоритм:
См. Пример здесь: https://github.com/dobromyslov/google-drive-utils/blob/511c44c2c48862b47c60038423b7f71bf1d28f49/src/index.ts#L150
И остерегайтесь квот GDrive:
источник