代码之家  ›  专栏  ›  技术社区  ›  TJR

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

  •  1
  • TJR  · 技术社区  · 10 年前

    我正在寻找一种根据图像大小在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函数中使用上面的代码片段时,我得到了以下错误:

    错误:具有不可读流的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时,脚本在“调用wrapAsync”后停止-而且没有返回错误,因此很难确定问题所在。我还用NPM包“imagesize”尝试了这一点 Meteor.wrapAsync(imagesize); 然后 imgsize(readStream) 这导致了相同的结果:在“call-wrapAsync:”之后没有控制台日志。

    1 回复  |  直到 10 年前
        1
  •  2
  •   Jasper Woudenberg    10 年前

    问题的核心不是 gm().size() ,但事实上 readStream 两次首先,使用它获取图像的大小 读取流 。然后您尝试再次使用它来调整大小,但由于它已结束,您会收到一个错误,告诉您流不可读。

    我在通用汽车包装的底部找到了解决方案 streams documenation :

    GOTCHA:处理输入流和任何“识别”操作时 (大小、格式等),如果您还 之后需要转换(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 指的是您正在处理的图像,您可以使用它来继续您的链。

    我在一个小样本流星应用程序中测试了这一点,它成功了!