CollectionFS图像未完全加载

时间:2014-07-23 14:04:38

标签: javascript jquery amazon-s3 meteor

我刚遇到一个令人讨厌的问题,看来我的图片有时只会略微加载。有时,当我手动刷新页面时,它们会完全加载,但很多时候会发生这种情况 - http://i.gyazo.com/a7050e430c79aa31ba557fc8271f1502.png

我不确定为什么会这样,我正在使用带有cfs-ejson文件和cfs-s3的collectionFS来存储图像。

这里有一些示例代码(主要配置文件图像)

模板代码 -

<div class="profile-avatar" style="height: 261px; margin-bottom: 30px;">
     {{#if avatar }}
       {{#if avatarReady }}
         <img width="261px" height="261px" src="{{avatar.url}}" class="profile-avatar-img thumbnail" alt="Profile Image">
        {{else}}
            <div class="activity-spinner">
                {{>spinner}}
            </div>
       {{/if}}
      {{else}}
      <img data-src="holder.js/100%x100%/text:No Profile Photo">
     {{/if}}  
</div> <!-- /.profile-avatar -->

Js代码 -

Template.profileLeft.helpers({
    avatar: function(){
        if(this.profile && this.profile.images)
            return Images.findOne(this.profile.images[0]._id);
    },
    avatarReady: function(){
        if(this.profile && this.profile.images){
            var image = Images.findOne(this.profile.images[0]._id);
            return image && image.isUploaded && image.hasStored("images");
        }
    },
});

1 个答案:

答案 0 :(得分:0)

我看到了与你描述的类似的问题。当我上传图像并立即显示它时,最初只会显示一部分图像。我会进入我发现的东西,希望它有所帮助。

我发现只有当我在CollectionFS中使用自定义transformWrite:函数时才会发生这种情况。我相信正在发生的是一种竞争条件导致image.isUploaded()和image.hasStored()函数在GraphicsMagick完成整个文件写入之前返回 true 。然后,Web服务器请求并缓存部分处理的图像。就像你说的,有时当你刷新时,图像将被完全加载。

举个例子:

显示部分处理过的图片的头像网址: http://yourdomain.com/cfs/files/images/Bun5qheJDeaZDp5Mf/DSC_5498.JPG?&store=images

添加假查询参数以绕过缓存,并显示完整图像: http://yourdomain.com/cfs/files/images/Bun5qheJDeaZDp5Mf/DSC_5498.JPG?&store=images&安培;胸围=高速缓存

我最终做的是在图像处理完毕后触发的模型上设置一个附加值。下面是处理图像的gm函数的示例。一旦函数完成,另一个函数被调用&#34; finishedProcessing&#34;设置模型的值。

示例代码:

gm(readStream, fileObj.name())
            .resize(1000).quality(75)
            .stream(function(err, stdout, stderr) {
                if (err) {
                    return err;
                }
                stdout.pipe(writeStream);

                // Update value when processing is finished
                stdout.on('end', function(){
                  finishedProcessing(fileObj._id);
                }); 
            });

然后,您可以在显示图像之前获取image.finishedProcessing的值:

avatarReady: function(){
        if(this.profile && this.profile.images){
            var image = Images.findOne(this.profile.images[0]._id);
            return image && image.isUploaded() && image.hasStored("images") && image.finishedProcessing;
        }
    }

这对我来说似乎很有效。即使您不使用GraphicsMagick,在处理或保存文件时也可能出现类似的情况。

另外,在旁注中,我相信你需要打电话给#34; image.isUploaded()&#34;而不是&#34; image.isUploaded&#34;在你的帮助函数中获取正确的返回值。

更新:在另一个附注中,我发现重构后如果你没有将你的收藏设置设置为允许更新,那么只会保存图像的第一个块,它也会导致你看到的问题。

Images.allow({
    update: function(userId, file, fields, modifier) {

        // This is to check whether or not CollectionFS is trying
        // to update the Image
        var validCFSUpdate = _.intersection(fields, ['chunkSize', 'chunkCount', 'chunkSize']).length > 0

        // Only allow logged in users and CollectionFS to update the Image
        return userId && validCFSUpdate;
    }
});