使用 GraphicsMagick 方法取决于 CollectionFS 的维度
Use GraphicsMagick methods depends on dimensions with CollectionFS
我正在寻找一种工作方式来根据图像大小在 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 时,脚本在 "call wrapAsync" 之后停止 - 也没有错误返回,因此很难判断问题出在哪里。我还尝试使用 NPM 包 "imagesize" 和 Meteor.wrapAsync(imagesize);
然后 imgsize(readStream)
导致相同的结果: "call wrapAsync:".
之后没有控制台日志
问题的核心不是 gm().size()
的异步行为,而是你两次使用 readStream
的事实。首先你用它来获取图像的大小,它清空 readStream
。然后您尝试再次使用它来调整大小,但因为它已经结束,您会收到一条错误消息,告诉您流不可读。
我在 gm 包的底部找到了解决方案 streams documenation:
GOTCHA: when working with input streams and any 'identify' operation
(size, format, etc), you must pass "{bufferStream: true}" if you also
need to convert (write() or stream()) the image afterwards NOTE: this
buffers the readStream in memory!
基于此和下面的小示例,我们可以将您的代码更改为:
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
指的是您正在处理的图像,您可以使用它来继续您的链。
我在一个小示例流星应用程序中对此进行了测试,它有效!
我正在寻找一种工作方式来根据图像大小在 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 时,脚本在 "call wrapAsync" 之后停止 - 也没有错误返回,因此很难判断问题出在哪里。我还尝试使用 NPM 包 "imagesize" 和 Meteor.wrapAsync(imagesize);
然后 imgsize(readStream)
导致相同的结果: "call wrapAsync:".
问题的核心不是 gm().size()
的异步行为,而是你两次使用 readStream
的事实。首先你用它来获取图像的大小,它清空 readStream
。然后您尝试再次使用它来调整大小,但因为它已经结束,您会收到一条错误消息,告诉您流不可读。
我在 gm 包的底部找到了解决方案 streams documenation:
GOTCHA: when working with input streams and any 'identify' operation (size, format, etc), you must pass "{bufferStream: true}" if you also need to convert (write() or stream()) the image afterwards NOTE: this buffers the readStream in memory!
基于此和下面的小示例,我们可以将您的代码更改为:
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
指的是您正在处理的图像,您可以使用它来继续您的链。
我在一个小示例流星应用程序中对此进行了测试,它有效!