如何优化用户上载的图像以及Meteor中服务器上的现有图像

时间:2019-04-15 15:34:47

标签: javascript amazon-s3 meteor

目前,我的小组正在运行一个流星应用程序,其中包含成千上万张全尺寸的图像。我们应该很久以前就已经做到了,但是我们需要一种优化它们以帮助缩短加载时间的方法。我正在寻找一种解决方案,以便在用户从我们的应用程序上载图像时将其保存为多种尺寸(例如:全尺寸,中型,缩略图),并且还可以自动旋转并允许用户旋转。我们使用Amazon S3托管所有图像。我们还需要一种从服务器端将所有现有图像转换为这些尺寸格式的方法。

我尝试过一段时间实现某些操作,但未成功。我在服务器上设置了imagemagick,但由于将图像临时保存在服务器内存中以进行处理而无法在生产环境中使用它,但是由于内存量有限而导致崩溃。我对这种事情几乎没有经验。

我的第二个想法是使用HTML画布来调整图像的大小。我认为这对新上传的图片有效。但是我仍在寻找一种处理现有图像的方法。

我考虑过:

  • 也许AWS有内置的方式来处理它们。我不介意那样做。
  • 某种流星/节点包可以帮助解决这个问题。
  • 设置另一个服务器以仅处理图像。
  • 使用一些第三方图像处理。

如果有人可以给我一些建议,这样我就可以大有帮助!

3 个答案:

答案 0 :(得分:2)

libvips可以在不使用内存或磁盘的情况下调整图像大小-像素以小块流经系统,同时进行解码和重新编码。

例如,以10k x 10k像素的JPG图像,我看到:

$ vipsheader wtc.jpg 
wtc.jpg: 9372x9372 uchar, 3 bands, srgb, jpegload
$ /usr/bin/time -f %M:%e vipsthumbnail wtc.jpg -s 5000x5000 -o x.jpg
98720:0.65

这是4核8线程i7。它使用98MB的内存,并需要0.65s的实时时间。有一个chapter in the docs introducing vipsthumbnail

为了进行比较,与ImageMagick 6相比,我看到了:

$ /usr/bin/time -f %M:%e convert wtc.jpg -resize 5000x5000 x.jpg
1263232:2.02

1.3GB的内存,需要2秒钟的实时时间–大约多10倍的内存,而慢3倍。

由于vipsthumbnail使用的内存很少,因此您可以将它与GNU并行结合使用,而无需服务器具有很多GB的内存。在此i7上,我可以一次有效地运行四个,并获得大约4倍的加速,因此总体上比ImageMagick快12倍。

sharp is a popular node binding for libvips,这可能更方便。也有针对Python,Ruby,PHP,Go,Lua等的绑定。

(免责声明:我是libvips的维护者之一,所以我不是很中立)

答案 1 :(得分:1)

我看到两种完全不同的预算有两种方法:

  1. 这不是我建议的方法,除非您只有1-2 GB(https://transloadit.com/demos/file-importing/resize-all-images-in-an-s3-bucket/

  2. 将您的S3链接到Cloudinary服务,然后使用Cloudinary进行转换(对于图像数量,您将不喜欢它($$))。

  3. 在AWS中,希望您使用Cloudfront服务您的资产。无论采用哪种转换技术,您都将主要做两件事:

    • 创建1个Lambda函数,以转换S3中所有新创建的资产。我要做的是“监视”一个S3存储桶,所有新事件触发我的Lambda函数,然后在其他2个文件夹中创建资产,最终得到:全分辨率,半分辨率和拇指分辨率。然后在Meteor中将各种尺寸链接到所需的尺寸。最典型的情况是,当您拥有用户个人资料图像时,需要在聊天中将其显示为完整标题,列表或小拇指。
    • 创建1个Lambda Edge(我相信会稍微增加一点$$),然后附加到您的Cloudfront Edge上以响应所有呼叫。如果对于当前存储量来说,对于您来说存储成本不是太高,则可以按要求转换图像并替换旧的较大图像,而不是一次执行一次批量运行。

您可以代替Lambda Edge,使用Node设置EC2计算机,并运行一个功能来遍历所有S3资产并进行转换。

无论如何,我觉得您想要做的就是所有AWS,而与您的Meteor无关。还有一件事要做:在上传图片之前先对其进行优化。如果您将React与Meteor结合使用,我可以为您提供必要的组件,否则,我可以为您提供这些组件,然后您编写Blaze视图层或您可以使用的其他任何东西。

如果您有兴趣使用这种方法,我会在基于ImageMagic的生产中使用Lambda转换功能。我还计划“升级”此功能以使用Sharp(如示例中所示),但是暂时它在生产中表现出色,有空时会切换。 检查此示例:

  Download the image from S3, transform, and upload to a different S3 bucket or folder.

  const dstKeyResizedHalf = `p-half/` + imageName
  s3.getObject({
    Bucket: srcBucket,
    Key: srcKey
  }).promise()
    .then(data => Sharp(data.Body)
      .jpeg({
        chromaSubsampling: '4:4:4',
        progressive: true
      })
      .resize(WEB_WIDTH_MAX)
      .toFormat('jpg')
      .toBuffer()
    )
    .then(buffer => s3.putObject({
      Body: buffer,
      Bucket: dstBucket,
      ContentType: 'image/jpg',
      Key: dstKeyResizedHalf,
      CacheControl: 'max-age=864000'
    }).promise())
    .catch(err => callback(err))
}

答案 2 :(得分:0)

我使用https://www.imagemagick.org/调整图像大小,裁剪和旋转图像。它与流星一起工作。这将是探索的良好起点。 https://github.com/CollectionFS/Meteor-CollectionFS