Как выполнить серию шагов обработки изображений во время выполнения в 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 ничего не делает.