it-swarm.com.ru

Node.js: изменение размера изображения без ImageMagick

Я разрабатываю веб-приложение для Node.js (+ экспресс 4), где пользователи могут установить изображение своего профиля, загрузив его на сервер. Мы уже ограничиваем размер файла mimetype и максимальный размер файла, поэтому пользователь не может загружать изображения размером более 200 КБ в png или jpeg.

Проблема в том, что мы хотели бы изменить (загружаемое на сервер) разрешение загружаемого изображения до 200x200, чтобы улучшить загрузку страниц и сэкономить место на диске. После некоторых исследований все ответы указывали на использование любого модуля на основе ImageMagick или GraphicsMagick.

Однако необходимость установки ImageMagick/GraphicsMagick для простого изменения размера изображения кажется мне слишком излишней, поэтому есть ли какое-либо иное решение, кроме этого, для Node.js?

Редактировать: Я изменил принятое решение на sharp , так как предыдущее решение (lwip) больше не поддерживается. Спасибо за все ваши отзывы!

65
zacr0

Я бы проголосовал за резко :

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 и многое другое.

Начиная с 0,20, npm автоматически загружает полные скомпилированные двоичные файлы на большинстве платформ, поэтому нет необходимости в нодномипе. Просто введите:

npm install sharp

или же:

yarn add sharp

И пошли.

66
jcupitt

Недавно я начал разработку модуля обработки изображений для 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 repo .

70
EyalAr

Посмотрите на lwip: https://github.com/EyalAr/lwip

Очень простой и удобный в использовании

npm install 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.
    });

});

Я успешно реализовал это в моем загрузчик файлов и он работает как шарм.

16
Arvind

Есть хорошая библиотека для работы с изображениями, написанная полностью на 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
});
10
edtech

острый в последнее время пользуется некоторой популярностью, но это та же идея, что и * Магические привязки.

Однако необходимость установить ImageMagick/GraphicsMagick для простого изменения размера изображения кажется мне слишком излишней.

Изменение размера изображения совсем не просто. Формат JPEG является особенно сложным, и существует несколько способов масштабирования графики с результатами различного качества, лишь немногие из них легко реализуются. Для этой работы существуют библиотеки обработки изображений, поэтому, если нет другой причины, по которой вы не можете их установить, воспользуйтесь этим.

8
Ry-

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
5
Dimitry Ivanov

Если вам не нужно большое изображение, вы можете изменить его размер на стороне клиента перед его загрузкой:

Чтение файлов в JavaScript с помощью File APIs

Изменение размера изображения на стороне клиента с помощью javascript перед загрузкой на сервер

Многие пользователи могут получить хорошее представление о себе со смартфона, и многие из них имеют размер более 200 КБ. Обратите внимание, что предоставленные клиентом данные не следует доверять, поэтому проверки на стороне сервера по-прежнему применяются.

3
Andrei Volgin

Я использовал lwip (как ранее было предложено arvind), но переключился на png-crop . Кажется, он работает немного быстрее (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 ...

1
Dan Caseley

Sharp работает очень хорошо и прост в использовании с потоками, работает как шарм, но вам нужно скомпилировать его с версией узла, это его недостаток. Я использовал 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 (), но это не помогло.

0
Alex Seceleanu