【问题标题】:Use GraphicsMagick methods depends on dimensions with CollectionFS使用 GraphicsMagick 方法取决于 CollectionFS 的尺寸
【发布时间】:2015-03-09 14:40:32
【问题描述】:

我正在寻找一种工作方式来使用 CollectionFS transformWrite 函数中的 GM 方法,具体取决于图像大小。在 GM 中实现了一个 size 方法,但这是异步工作的,因此似乎无法使用。

我尝试了以下方法:

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 函数中使用上述 sn-p 时,我收到此错误:

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

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

只有访问fileObjreadStreamwriteStream 时,是否有解决方案以同步方式获取图像的尺寸?

编辑:

感谢 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 时,脚本在“调用 wrapAsync”后停止 - 也没有返回错误,因此很难判断问题所在。我还尝试使用带有Meteor.wrapAsync(imagesize);imgsize(readStream) 的NPM 包“imagesize”,这会导致相同的结果:“call wrapAsync:”之后没有控制台日志。

【问题讨论】:

    标签: node.js meteor graphicsmagick


    【解决方案1】:

    问题的核心不是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 指的是您正在处理的图像,您可以使用它来继续您的链。

    我在一个小示例流星应用程序中对此进行了测试,它可以工作!

    【讨论】:

    • 感谢 github 参考。我明天会检查一下,如果可行,我会告诉你信息。
    • 太伤心了:我不知道为什么,但这似乎不起作用。在 getSize() 步骤之后,代码停止......此后不会执行任何 console.log。我对其进行了测试,在 getSize() 之前我添加了一个 console.log(getSize) (返回 [function])但是当 console.log(getSize());console.log('test');什么都不会返回。
    • 嘿 Jasper 我编辑了我的问题,也许这可以帮助您了解问题可能是什么?
    • 我正在检查,会尽快回复您!
    • 好的,我追溯了你的步骤,可以重现函数挂起的问题。我将头撞在墙上一会儿,但无法找出失败的原因。这是一个公开的谜。但是,在玩耍时,我注意到您在回调中将流连接在一起的最初想法确实对我有用!原来您的问题与异步行为无关,而是与其他问题有关,所以我重写了我的答案。让我知道这是否适合您!
    猜你喜欢
    • 2023-03-22
    • 1970-01-01
    • 2014-06-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多