Подтвердить что ты не робот

Изменение размера и обрезка изображения и сохранение пропорций NodeJS & gm

Я пытаюсь создать несколько эскизов, используя пакет gm от NodeJS, но мне не повезло. Мне нужно изменить размер изображений размером более 600x600 (может быть любая ширина/высота, начиная с заданного), но когда я передаю размер gm, он создает изображение, которое не имеет того же размера, который я запрашивал.

Например, учитывая этот код, я предполагаю, что при запуске node app /path/to/image.png я получу изображение размером 200x100, но вместо этого я получил, скажем, изображение 180x100 или 200x90...

gm(fileLocation)
    .thumb(200, 100, 'processed.' + process.argv[2].split('.').pop(), function() {
        console.log("Done!");
    });

Я также попробовал вариант изменения размера. Там даже возможность форсировать размер, но соотношение сторон выхода идет ужасно...

gm('/path/to/image.jpg')
    .resize(353, 257)
    .write(writeStream, function (err) {
         if (!err) console.log(' hooray! ');
    });
4b9b3361

Ответ 1

Попробуйте с пакетом imagemagick для NodeJS: https://github.com/yourdeveloper/node-imagemagick

im.crop({
    srcPath: process.argv[2],
    dstPath: 'cropped.' + process.argv[2].split('.').pop(),
    width: 200,
    height: 200,
    quality: 1,
    gravity: 'Center'
}, function(err, stdout, stderr){
    if (err) throw err;
    console.log('resized ' + process.argv[2].split('/').pop() + ' to fit within 200x200px');
});

Обновление: Обратите внимание, что пакет node-imagemagick не был обновлен достаточно долго. Пожалуйста, рассмотрите ответ Freyday, поскольку он является самым современным.

Ответ 2

Чтобы достичь размера, обрезанного изображения с центром тяжести с помощью модуля gm, вы можете использовать что-то похожее на это:

gm('/path/to/image.jpg')
  .resize('200', '200', '^')
  .gravity('Center')
  .crop('200', '200')
  .write(writeStream, function (err) {
    if (!err) console.log(' hooray! ');
  });

Аргумент '^' в функции resize покажет GraphicsMagick, чтобы использовать высоту и ширину как минимум, а не по умолчанию. Результирующее измененное изображение будет иметь либо ширину, либо высоту вашего назначенного размера, в то время как несоответствующий размер больше указанного размера.

Затем функция gravity сообщает GraphicsMagick, как должна себя вести следующая функция crop, которая обрезает изображение до конечного размера.

Подробную документацию по параметрам GraphicsMagick, используемым модулем gm, можно найти здесь: http://www.graphicsmagick.org/GraphicsMagick.html

Ответ 3

Другим решением без внешних библиотек (кроме imagemagick) является создание собственного решения:

var exec = require('child_process').exec;

resize = function (image) {
  var cmd = 'convert ' + image.src + 
  ' -resize ' + image.width + 'x' + image.height + '^' + 
  ' -gravity center -crop ' + image.width + 'x' + image.height + '+0+0 ' +
  image.dst;

  exec(cmd, function(error, stdout, stderr) {
    if(error) {
      console.log(error);
    }
  });
}

И затем назовите его:

resize({
    src: sourceFile,
    dst: destinyFile,
    width: 320,
    height: 240
});

Это позволит вам настраивать параметры качества, обрезки, водяные знаки и т.д.

Ответ 4

Попробуйте использовать пакет Jimp для Node.js https://www.npmjs.com/package/jimp. Который лучше гм, я думаю. Не требует никаких зависимостей. Я пытался использовать gm раньше, но я не смог установить зависимости для gm. В итоге я использовал jimp, и все работало нормально.

   Jimp.read('lenna.png', (err, lenna) => {
      if (err) throw err;
      lenna
        .resize(256, 256) // resize
        .write('lena-small-bw.jpg'); // save
    });

Ответ 5

Две вещи...

1) https://github.com/rsms/node-imagemagick - Этот пакет больше не поддерживается. Я бы порекомендовал оригинальный пакет, который вы использовали.

2) Причина, по которой он не изменяется, заключается в том, что функция .resize принимает строку, а не целое число. Он должен быть... ('353', '257')

gm('/path/to/image.jpg')
    .resize('353', '257')
    .write(writeStream, function (err) {
         if (!err) console.log(' hooray! ');
    });