Изменение размера и обрезка изображения и сохранение пропорций 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! ');
});
Ответы
Ответ 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! ');
});