Как выполнить серию шагов обработки изображений во время выполнения в Node.js

Я использую модуль gm Node для обрезки и создания эскизов изображений. Вот что я пытаюсь сделать...

var img = gm("./myImage.jpg");
var thmb;

if(options.crop)
   img = img.crop(100, 50, 10, 10);

if(options.resize)
   thmb = img.resize(240);

img.stream(callback);

if(thmb)
   thmb.stream(callback2);

Ожидаемый результат:

Приведенный выше код должен выводить два изображения ("img" и "thmb"). 'img' должна быть обрезанной версией исходного изображения, а 'thmb' должна быть обрезанной и измененной версией оригинала.

Фактический результат

Вывод 'img' обрезается, как и ожидалось, но 'thmb' является ТОЛЬКО измененной версией исходного изображения. Это не обрезается, как ожидалось. Что я делаю неправильно?

1 ответ

Решение

Путь gm Работает, вы должны использовать одну цепочку преобразований для каждого желаемого выхода, даже если ввод одинаковый. Так что если вы хотите сделать A и B на файл foo.jpgи поместите вывод в один файл, и сделайте только B для одного и того же входного файла, но поместите вывод в другой файл, вам нужно будет сделать:

var gm = require("gm");
gm("./foo.jpg").A().B().stream(...);
gm("./foo.jpg").B().stream(...);

Операции над объектами, возвращаемыми gm вернуть тот же объект, который они вызывали. Так img.crop(...) === img правда. В примере используются crop но это в целом верно и для других операций. Так что если вы делаете thmb = img.resize(...) затем после этой операции thmb === img правда. Вот почему вы должны создать два отдельных объекта с gm(...),

Так что-то вроде этого должно делать то, что вы хотите:

var gm = require("gm");
var fs = require("fs");

options = {
    resize: true,
    crop: true
};

var img = gm("./myImage.jpg");
var thmb = options.resize ? gm("./myImage.jpg") : undefined;

if(options.crop)
   img = img.crop(500, 50, 10, 10);
   if (thmb)
       thmb = thmb.crop(500, 50, 10, 10);

if(options.resize)
    thmb = thmb.resize(240);

img.stream(function (err, stdout, stderr) {
    stdout.pipe(fs.createWriteStream("./out.jpg"));
});


if(thmb)
   thmb.stream(function (err, stdout, stderr) {
       stdout.pipe(fs.createWriteStream("./thumb.jpg"));
   });

Я изменил параметры обрезки, чтобы получить ширину 500, потому что изменение размера до 240 после обрезки до ширины 100 ничего не делает.

Другие вопросы по тегам