【问题标题】:Best way to save images on Amazon S3 and distribute them using CloudFront在 Amazon S3 上保存图像并使用 CloudFront 分发它们的最佳方式
【发布时间】:2017-06-30 11:12:07
【问题描述】:

我正在处理的应用程序(nodejs)有用户配置文件,每个配置文件可以有多个图像。我使用 S3 作为我的主要存储和 CloudFront 来分发它们。

问题是有时用户上传大图像,我想做的是在下载图像时缩放图像(在 html img 标签或手机中查看),主要是因为性能。

我不知道是否应该在将图像上传到 S3 之前对其进行缩放(可能使用 lwip https://github.com/EyalAr/lwip),或者在通过 CloudFront 下载图像时是否可以缩放图像或获取低质量图像?我读过 CloudFront 可以使用 Gzip 压缩文件,但也不推荐用于图像。

由于存储的原因,我也不想将缩放 + 原始图像上传到 S3。

应该在客户端、服务器还是 S3 中完成?最好的方法是什么?

【问题讨论】:

    标签: node.js amazon-s3 amazon-cloudfront image-scaling


    【解决方案1】:

    通过 CloudFront 下载图像时,是否可以缩放图像或获得低质量图像?

    没有这样的功能。如果您希望对图像进行调整大小、重新采样、缩放、压缩等操作,则需要在将其保存到 S3 中的最终位置之前进行。

    请注意,我说的是它在 S3 中的最终位置。

    一种解决方案是将图像上传到 S3 中的 中间 位置,可能在不同的存储桶中,然后使用修改图像的代码调整其大小并将其存储在最终的 S3 位置,从那里CloudFront 将代表下载用户获取它。

    我了解到 CloudFront 可以使用 Gzip 压缩文件,但也不推荐用于图像。

    图像从 gzip 压缩中受益甚少,但 CloudFront 文档还指出 CloudFront doesn't compress anything that isn't in some way formatted as text,它往往从 gzip 压缩中受益更多。

    由于存储的原因,我也不想将缩放 + 原始图像上传到 S3。

    我认为这是你的错误。

    “压缩”图像与压缩 zip 文件不同。压缩图像有损。您无法从压缩版本重建原始图像,因为此处讨论的图像压缩(根据定义)是故意丢弃图像中的信息,使其尺寸在所需范围内且质量在可接受范围内.图像压缩既是一门科学,也是一门艺术。如果您不保留原始图像,并且您后来决定要修改图像压缩算法(或者因为您后来决定尺寸仍然太大,或者因为您认为原始算法过于激进并导致无法接受的低质量),您无法再次通过压缩算法运行已压缩的图像而不会进一步降低质量。

    使用 S3 的 STANDARD_IA(“不频繁访问”)存储类将原始图像的存储成本降低一半,以换取更昂贵的下载——因为这些图像很少会被再次下载,因为只有你会知道它们在存储桶中的 URL。

    应该在客户端、服务器还是 S3 中完成?

    它不能“在”S3 中完成,因为 S3 只存储对象。它不会操纵它们。

    这留下了两个选择,但在服务器上执行此操作有多种选择。

    当您说“服务器”时,您可能会想到您的网络服务器。这是一种选择,但此过程可能会占用大量资源,因此您需要在可扩展性计划中考虑到这一点。

    GitHub 上有一些项目,例如 this one,旨在使用 AWS Lambda 来执行此操作,它按需提供“无服务器”代码执行。代码在服务器上运行,但它不是您必须配置或维护的服务器,或者在它不活动时付费——Lambda 以 100 毫秒为增量计费。这是第二个选项。

    在客户端上做这当然是一种选择,但似乎可能更有问题和容易出错,更不用说某些解决方案将是特定于平台的。

    没有完成这项任务的“最佳”方式。

    如果您不熟悉 EXIF 元数据,您也需要熟悉它。除了重新采样/调整大小之外,您可能还需要从用户提供的图像中删除一些元数据,以避免泄露您的用户可能没有意识到附加到他们的图像的敏感数据 - 例如照片所在的 GPS 坐标采取。一些网站还会为用户提交的图片添加水印,这也是您可能同时做的事情。

    【讨论】:

    • 非常翔实和详细!很好的答案,赞成。
    • 我编辑了我的问题,我想问有没有办法,而不是我写了有办法,我的错。非常感谢您的回答,非常好的信息。
    • @IbraheemAl-Saady 谢谢,我已经更新了我对问题的引用以匹配您的编辑。
    • 谢谢你,@Sneak。
    【解决方案2】:

    我会将图像存储在 STANDARD_IA 中的 S3 中,然后使用 Lambda 运行 nodejs 和 sharp 动态调整它们的大小以完成繁重的工作。我相信 Google 会做类似的事情,因为您可以请求任何维度的个人资料 img。

    AWS Networking & Content Deliver 博客中有一篇文章可能会为您提供很多所需的内容。 Check it out here.

    基本思路是这样的:

    1. 像往常一样将图像上传到 S3(如果需要,您可以执行 STANDARD_IA 以节省成本)
    2. 使用查询参数向 Cloudfront 发送请求,其中包括您想要的图像大小(即 https://static.mydomain.com/images/image.jpg?d=100×100)
    3. 使用 Lambda Edge 函数,您可以构建调整大小的图像并根据需要将它们存储在 s3 中,然后再通过 CDN 提供。创建调整大小的版本后,它在 S3 中始终可用
    4. Cloudfront 返回刚刚创建的新调整大小的图像。

    它需要更多的工作,但它可以让您根据需要调整大小以适应您想要/需要的任何大小。它还使您可以灵活地随时从 UI 更改要提供给客户端的 img 大小。这里有几个类似的帖子。有些甚至不使用 Cloudfront,而是通过 ApiGateway 作为中介提供服务。

    https://aws.amazon.com/blogs/compute/resize-images-on-the-fly-with-amazon-s3-aws-lambda-and-amazon-api-gateway/

    https://github.com/awslabs/serverless-image-resizing

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-10-05
      • 1970-01-01
      • 1970-01-01
      • 2013-01-28
      • 2017-10-04
      • 1970-01-01
      • 2011-04-16
      • 2013-12-20
      相关资源
      最近更新 更多