使用GraphicsMagick方法取决于具有CollectionFS的维度

时间:2015-03-09 14:40:33

标签: node.js meteor graphicsmagick

我正在寻找一种工作方式,根据图像大小在CollectionFS transformWrite函数中使用GM方法。在GM中实现了一种大小方法,但这种方法同步,因此似乎无法使用。

我尝试了以下内容:

gm(readStream, fileObj.name()).size(function(err, dimensions){
    if (err) {
        console.log('err with getting size:');
        console.log(err);
    }
    console.log('Result of media_size:');
    console.log(dimensions);
    // here do smth depends on the dimensions ...

    gm(readStream, fileObj.name()).resize('1200', '630').stream().pipe(writeStream);


});

当我在CollectionFS函数中使用上面的代码片段时,我收到此错误:

错误:gm()。stream()或gm()。write()带有不可读的流。

这似乎是我使用异步功能的一个问题 - 当删除异步功能时,上传工作完美但我无法访问上传图像的尺寸。

当只能访问fileObjreadStream&时,是否有解决方案以同步方式获取图片的尺寸writeStream

修改

感谢Jasper使用wrapAsync提示。我测试了它并使用了这段代码:

var imgsize;
var img = gm(readStream, fileObj.name());
imgsize = Meteor.wrapAsync(img.size, img);
console.log('call wrapAsync:');
var result;
try {
    result = imgsize();
} catch (e) {
    console.log('Error:');
    console.log(e)
}
console.log('((after imgsize()))');

当看一下console.logs时,脚本会在#34; call wrapAsync"之后停止。 - 也没有错误返回所以很难说出问题是什么。我也尝试过使用NPM包" imagesize"使用Meteor.wrapAsync(imagesize);然后imgsize(readStream)导致相同的内容:"调用wrapAsync:"。

之后没有控制台日志

1 个答案:

答案 0 :(得分:2)

问题的核心不是gm().size()的异步行为,而是您使用readStream两次的事实。首先,您使用它来获取图像的大小,这会清空readStream。然后你尝试再次使用它来调整大小,但因为它已经结束,你会收到一个错误,告诉你该流是不可读的。

我在gm包的streams documenation

的底部找到了解决方案
  

GOTCHA:处理输入流和任何“识别”操作时   (大小,格式等),如果你也必须传递“{bufferStream:true}”   之后需要转换(write()或stream())图片注意:这个   将readStream缓冲在内存中!

基于此以及下面的小例子,我们可以将您的代码更改为:

gm(readStream, fileObj.name()).size({ bufferStream: true }, function(err, dimensions){
    if (err) {
        console.log('err with getting size:');
        console.log(err);
    }
    console.log('Result of media_size:');
    console.log(dimensions);
    // here do smth depends on the dimensions ...

    this.resize('1200', '630').stream().pipe(writeStream);
});

在回调中,this指的是您正在处理的图片,您可以使用它继续您的链。

我在一个小样本流星应用程序中对此进行了测试,它确实有效!