我正在寻找一种工作方式,根据图像大小在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()带有不可读的流。
这似乎是我使用异步功能的一个问题 - 当删除异步功能时,上传工作完美但我无法访问上传图像的尺寸。
当只能访问fileObj
,readStream
&时,是否有解决方案以同步方式获取图片的尺寸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:"。
答案 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
指的是您正在处理的图片,您可以使用它继续您的链。
我在一个小样本流星应用程序中对此进行了测试,它确实有效!