如何在运行时在Node.js中执行一系列的image processing步骤

我正在使用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'应该是原始的裁剪和resize的版本。

实际结果

“img”输出按预期裁剪,但“thmb”只是原始图像的缩放版本。 它没有按预期裁剪。 我究竟做错了什么?

gm工作方式,即使input相同,也必须对每个期望的输出使用一个转换链。 所以如果你想在一个文件foo.jpg上做A和B,并把输出放在一个文件中,并且只对相同的input文件进行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(...)创build两个独立的对象。

所以像这样的事情应该做你想做的事情:

 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,因为在裁剪到100的宽度后,调整到240的宽度没有任何作用。