使用亚马逊(AWS)云服务在S3上实现图片缩放功能(CloudFront/S3[AccessPoint/LambdaAccessPoint])

这篇具有很好参考价值的文章主要介绍了使用亚马逊(AWS)云服务在S3上实现图片缩放功能(CloudFront/S3[AccessPoint/LambdaAccessPoint])。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

亚马逊云服务中的S3对象存储功能和国内阿里云的oss对象存储使用基本一致。但是涉及到存储内容处理时,两家有些差别。

比如:对于云存储中的图片资源,阿里云比较人性化对于基本的缩放裁剪功能已经帮我们封装好了,只需要在url地址后面拼接参数即可,但是亚马逊S3存储本身并不具备这个功能,但是亚马逊提供了很多种方式,虽然灵活但是使用门槛较高(尤其是亚马逊文档基本都是英文的🤣)。

下面详细说一下如何在亚马逊服务上基于S3存储实现图片处理(扩展开可以处理任意类型存储资源)

篇幅较长,看完能懂个大概

使用到的亚马逊服务:

Lambda函数服务:云服务商目前都在推的serverless一种实现,在云端特定功能上运行写好的代码,支持很多种语言,弹性扩展灵活方便。参考(首先要学会简单的创建lambda函数,后面需要使用函数处理图片)

S3对象存储:

        Access Point:作为S3存储的一个外部访问入口,一个access point对应一个S3bucket,一个S3 bucket可以对应多个access point. 常用于外部访问S3存储数据。

        Object Lambda Access Point:建立在Access Point之上的Lambda函数切点,可以对访问请求或者响应做进一步处理,或者修改。

CloudFront云端内容分发服务(cdn):亚马逊云端内容分发服务,实现对内容的实时定制化处理,可扩展性高,延迟低。

S3 + CloudFront + Lambda 实现图片缩放具体步骤

1. 在lambda控制台新建Lambda函数 参考:geting-started 本文所需代码如下:

注:代码来自亚马逊文档中的示例,稍作修改实现图片缩放功能

import boto3
import json
import os
import logging
from io import BytesIO
from PIL import Image, ImageDraw, ImageFont
from urllib import request
from urllib.parse import urlparse, parse_qs, unquote
from urllib.error import HTTPError
from typing import Optional

logger = logging.getLogger('S3-img-processing')
logger.addHandler(logging.StreamHandler())
logger.setLevel(getattr(logging, os.getenv('LOG_LEVEL', 'INFO')))
FILE_EXT = {
    'JPEG': ['.jpg', '.jpeg'],
    'PNG': ['.png'],
    'TIFF': ['.tif']
}
OPACITY = 64  # 0 = transparent and 255 = full solid


def get_img_encoding(file_ext: str) -> Optional[str]:
    result = None
    for key, value in FILE_EXT.items():
        if file_ext in value:
            result = key
            break
    return result

# 添加水印示例
def add_watermark(img: Image, text: str) -> Image:
    # font = ImageFont.truetype("AmazonEmber_Rg.ttf", 82)
    txt = Image.new('RGBA', img.size, (255, 255, 255, 0))
    if img.mode != 'RGBA':
        image = img.convert('RGBA')
    else:
        image = img

    d = ImageDraw.Draw(txt)
    # Positioning Text
    width, height = image.size
    text_width, text_height = d.textsize(text, font)
    x = width / 2 - text_width / 2
    y = height / 2 - text_height / 2
    # Applying Text
    d.text((x, y), text, fill=(255, 255, 255, OPACITY), font=font)
    # Combining Original Image with Text and Saving
    watermarked = Image.alpha_composite(image, txt)
    return watermarked

# 图片缩放
def resize_image(img, max_side_length=768):
    # 打开图像文件
    width, height = img.size
    print("原:宽X高", width, "x", height)
    # 计算缩放后的尺寸
    scale_factor = max_side_length / max(width, height)
    new_width = int(width * scale_factor)
    new_height = int(height * scale_factor)

    # 缩放图像
    resized_img = img.resize((new_width, new_height))
    return resized_img

def handler(event, context) -> dict:
    logger.debug(json.dumps(event))
    object_context = event["getObjectContext"]
    # Get the presigned URL to fetch the requested original object
    # from S3
    s3_url = object_context["inputS3Url"]
    # Extract the route and request token from the input context
    request_route = object_context["outputRoute"]
    request_token = object_context["outputToken"]
    parsed_url = urlparse(event['userRequest']['url'])
    object_key = parsed_url.path
    logger.info(f'Object to retrieve: {object_key}')
    parsed_qs = parse_qs(parsed_url.query)
    for k, v in parsed_qs.items():
        parsed_qs[k][0] = unquote(v[0])

    filename = os.path.splitext(os.path.basename(object_key))
    # Get the original S3 object using the presigned URL
    logger.info(f'S3 url: {s3_url}, parsed_url: {parsed_url}')
    req = request.Request(s3_url)
    try:
        response = request.urlopen(req)
    except HTTPError as e:
        logger.info(f'Error downloading the object. Error code: {e.code}')
        logger.exception(e.read())
        return {'status_code': e.code}

    if encoding := get_img_encoding(filename[1].lower()):
        logger.info(f'Compatible Image format found! Processing image: {"".join(filename)}')
        img = Image.open(response)
        logger.debug(f'Image format: {img.format}')
        logger.debug(f'Image mode: {img.mode}')
        logger.debug(f'Image Width: {img.width}')
        logger.debug(f'Image Height: {img.height}')

        # img_result = add_watermark(img, parsed_qs.get('X-Amz-watermark', ['Watermark'])[0])
        img_result = img
        if parsed_qs.get('size', [''])[0] != '':
            img_result = resize_image(img, int(parsed_qs.get('size', ['500'])[0], base=10))
        img_bytes = BytesIO()

        if img.mode != 'RGBA':
            # Watermark added an Alpha channel that is not compatible with JPEG. We need to convert to RGB to save
            img_result = img_result.convert('RGB')
            img_result.save(img_bytes, format='JPEG')
        else:
            # Will use the original image format (PNG, GIF, TIFF, etc.)
            img_result.save(img_bytes, encoding)
        img_bytes.seek(0)
        transformed_object = img_bytes.read()

    else:
        logger.info(f'File format not compatible. Bypass file: {"".join(filename)}')
        transformed_object = response.read()

    # Write object back to S3 Object Lambda
    s3 = boto3.client('s3')
    # The WriteGetObjectResponse API sends the transformed data
    if os.getenv('AWS_EXECUTION_ENV'):
        s3.write_get_object_response(
            Body=transformed_object,
            RequestRoute=request_route,
            RequestToken=request_token)
    else:
        # Running in a local environment. Saving the file locally
        with open(f'myImage{filename[1]}', 'wb') as f:
            logger.debug(f'Writing file: myImage{filename[1]} to the local filesystem')
            f.write(transformed_object)

    # Exit the Lambda function: return the status code
    return {'status_code': 200}

创建完成如下:

使用亚马逊(AWS)云服务在S3上实现图片缩放功能(CloudFront/S3[AccessPoint/LambdaAccessPoint]),云服务,aws,云计算,s3,cloudfront,accesspoint

2. 亚马逊S3控制台左侧 Access Point 菜单创建Access Point

使用亚马逊(AWS)云服务在S3上实现图片缩放功能(CloudFront/S3[AccessPoint/LambdaAccessPoint]),云服务,aws,云计算,s3,cloudfront,accesspoint

使用亚马逊(AWS)云服务在S3上实现图片缩放功能(CloudFront/S3[AccessPoint/LambdaAccessPoint]),云服务,aws,云计算,s3,cloudfront,accesspoint

使用亚马逊(AWS)云服务在S3上实现图片缩放功能(CloudFront/S3[AccessPoint/LambdaAccessPoint]),云服务,aws,云计算,s3,cloudfront,accesspoint

3.   亚马逊S3控制台左侧 Object Lambda Access Point 菜单创建Object Lambda Access Point

使用亚马逊(AWS)云服务在S3上实现图片缩放功能(CloudFront/S3[AccessPoint/LambdaAccessPoint]),云服务,aws,云计算,s3,cloudfront,accesspoint

使用亚马逊(AWS)云服务在S3上实现图片缩放功能(CloudFront/S3[AccessPoint/LambdaAccessPoint]),云服务,aws,云计算,s3,cloudfront,accesspoint

 其他选项保持默认,点击创建Object Lambda Access Point即可

4. CloudFront控制台创建分发

使用亚马逊(AWS)云服务在S3上实现图片缩放功能(CloudFront/S3[AccessPoint/LambdaAccessPoint]),云服务,aws,云计算,s3,cloudfront,accesspoint

使用亚马逊(AWS)云服务在S3上实现图片缩放功能(CloudFront/S3[AccessPoint/LambdaAccessPoint]),云服务,aws,云计算,s3,cloudfront,accesspoint

使用亚马逊(AWS)云服务在S3上实现图片缩放功能(CloudFront/S3[AccessPoint/LambdaAccessPoint]),云服务,aws,云计算,s3,cloudfront,accesspoint

其他先保持默认,点击创建分发。

 5. 上面分别创建了所需资源,下面需要为上面创建的资源和S3 bucket配置访问策略权限。

      配置Bucket访问策略 ,点击bucket name名称进入下图,最后点击Bucket policy右侧的edit编辑按钮

使用亚马逊(AWS)云服务在S3上实现图片缩放功能(CloudFront/S3[AccessPoint/LambdaAccessPoint]),云服务,aws,云计算,s3,cloudfront,accesspoint

 修改如下配置,保存。 (下面的配置为允许aws的所有服务访问s3内的指定bucket内所有对象,并且AccessPoint的账号等于指定的账号)

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "*"
            },
            "Action": "*",
            "Resource": [
                "arn:aws:s3:::你的bucket名称",
                "arn:aws:s3:::你的bucket名称/*"
            ],
            "Condition": {
                "StringEquals": {
                    "s3:DataAccessPointAccount": "当前登录的账号ID"
                }
            }
        }
    ]
}

 配置Access Point访问策略

使用亚马逊(AWS)云服务在S3上实现图片缩放功能(CloudFront/S3[AccessPoint/LambdaAccessPoint]),云服务,aws,云计算,s3,cloudfront,accesspoint

配置内容如下:(下面配置为允许lambda access point访问点  访问  当前 access point内所有对象资源)

{
    "Version": "2012-10-17",
    "Id": "default",
    "Statement": [
        {
            "Sid": "s3objlambda",
            "Effect": "Allow",
            "Principal": {
                "Service": "cloudfront.amazonaws.com"
            },
            "Action": "s3:*",
            "Resource": [
                "arn:aws:s3:你的区域:当前帐号ID:accesspoint/你的AccessPoint名子标识(我这里是vapp-aws-image)",
                "arn:aws:s3:你的区域:当前帐号ID:accesspoint/你的AccessPoint名子标识/object/*"
            ],
            "Condition": {
                "ForAnyValue:StringEquals": {
                    "aws:CalledVia": "s3-object-lambda.amazonaws.com"
                }
            }
        }
    ]
}

配置Object Lambda Access Point访问策略
使用亚马逊(AWS)云服务在S3上实现图片缩放功能(CloudFront/S3[AccessPoint/LambdaAccessPoint]),云服务,aws,云计算,s3,cloudfront,accesspoint

 配置策略如下:(下面的配置为允许登陆账号下的内容分发  访问指定的object lambda access point)

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Service": "cloudfront.amazonaws.com"
            },
            "Action": "s3-object-lambda:Get*",
            "Resource": "arn:aws:s3-object-lambda:你的区域:登录账号ID:accesspoint/你的ObjectLambdaAccessPoint名字",
            "Condition": {
                "StringEquals": {
                    "aws:SourceArn": "arn:aws:cloudfront::登录账号ID:distribution/刚才创建的分发ID"
                }
            }
        }
    ]
}

6. 资源和策略配置完成后,还有最后一步就是自定义访问参数,用于缓存生成的内容,避免每次访问都需要调用lambda函数处理(或者缓存了不正确的内容,因为默认缓存策略不包含自定义参数),本文自定义参数为size,表示当前图片最大边边长尺寸,等比缩放,需要为自定义参数创建一个Cache policy

使用亚马逊(AWS)云服务在S3上实现图片缩放功能(CloudFront/S3[AccessPoint/LambdaAccessPoint]),云服务,aws,云计算,s3,cloudfront,accesspoint

使用亚马逊(AWS)云服务在S3上实现图片缩放功能(CloudFront/S3[AccessPoint/LambdaAccessPoint]),云服务,aws,云计算,s3,cloudfront,accesspoint

 使用亚马逊(AWS)云服务在S3上实现图片缩放功能(CloudFront/S3[AccessPoint/LambdaAccessPoint]),云服务,aws,云计算,s3,cloudfront,accesspoint

 创建成功后,找到刚才创建的CloudFront分发,配置缓存策略如下:

使用亚马逊(AWS)云服务在S3上实现图片缩放功能(CloudFront/S3[AccessPoint/LambdaAccessPoint]),云服务,aws,云计算,s3,cloudfront,accesspoint

使用亚马逊(AWS)云服务在S3上实现图片缩放功能(CloudFront/S3[AccessPoint/LambdaAccessPoint]),云服务,aws,云计算,s3,cloudfront,accesspoint

 保存后,等会(几分钟)生效。

7. 测试

CloudFront控制台,找到刚才创建的Distribution分发,找到分发域名,如下图:

使用亚马逊(AWS)云服务在S3上实现图片缩放功能(CloudFront/S3[AccessPoint/LambdaAccessPoint]),云服务,aws,云计算,s3,cloudfront,accesspoint

 到bucket中上传一个图片,然后使用该域名访问测试如下:

使用亚马逊(AWS)云服务在S3上实现图片缩放功能(CloudFront/S3[AccessPoint/LambdaAccessPoint]),云服务,aws,云计算,s3,cloudfront,accesspoint

如果写的lambda函数有问题,会报错,到lambda控制台查找日志根据报错信息调试即可。 

 上面截图中使用的为英文版控制台,原因是由于亚马逊很多文档都是英文,个别有中文的翻译也不好,对比英文文档使用时会出现对不上号的情况,所以推荐大家使用亚马逊对应文档操作时使用英文控制台。

最后 理一下这套服务整个流程

使用亚马逊(AWS)云服务在S3上实现图片缩放功能(CloudFront/S3[AccessPoint/LambdaAccessPoint]),云服务,aws,云计算,s3,cloudfront,accesspoint

参考:amazon-s3-object-lambda-with-cloudfront文章来源地址https://www.toymoban.com/news/detail-563558.html

到了这里,关于使用亚马逊(AWS)云服务在S3上实现图片缩放功能(CloudFront/S3[AccessPoint/LambdaAccessPoint])的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 亚马逊Web服务(AWS)的几个主要应用

    以下是亚马逊Web服务(AWS)的几个主要应用: EC2(弹性计算云):提供虚拟计算资源,可为应用程序和服务提供计算能力。 S3(简单存储服务):提供高度可扩展和可靠的对象存储,可用于存储大量数据和文件。 RDS(关系型数据库服务):提供易于设置、操作和扩展的关系

    2024年02月12日
    浏览(34)
  • 【BIT云计算实验】亚马逊云服务(AWS)实验记录

    前置知识:Linux基本指令使用,拥有一张visa银行卡 实验时间:1h 实验难度(采用Codeforces的rating标准): 拥有visa银行卡:div2A / 800 未拥有visa银行卡:Impossible 注意:本次实验使用的服务器不额外收取费用。在进行这个实验之前,确保自己有一张visa银行卡,不然无法注册Amaz

    2023年04月08日
    浏览(53)
  • 亚马逊AWS上怎么创建Linux 服务器?操作难不难?

    AWS(Amazon Web Services)是全球领先的云服务器提供商之一。你可以使用 AWS 平台在一分钟内设置完服务器。在 AWS 上,你可以微调服务器的许多技术细节,如 CPU 数量,内存和磁盘空间,磁盘类型(更快的 SSD 或者经典的 IDE)等。关于 AWS ***的一点是,你只需要为你使用到的服务付费。

    2024年04月16日
    浏览(28)
  • 亚马逊云服务器aws ssh无法登录的解决问题记录

    一、涉及命令 二、AWS亚马逊云EC2服务器使用Root登录方法(在debian系统上操作成功) 三、SSH密钥丢失,更换密钥方法 解决连接到 EC2 实例时的“服务器拒绝我们的密钥”错误 四、可疑方法 1、将具有 SSH 访问权限的新用户账户添加到 Amazon EC2 Linux 实例 2、使用 EC2 串行控制台

    2024年02月06日
    浏览(26)
  • 【免费外国云服务器】亚马逊AWS创建EC2实例搭建个人服务器

    作者:20岁爱吃必胜客(坤制作人),近十年开发经验, 跨域学习者,目前于海外某世界知名高校就读计算机相关专业。 荣誉: 阿里云博客专家认证 、腾讯开发者社区优质创作者,在CTF省赛校赛多次取得好成绩。 跨领域学习 ,喜欢摄影、弹吉他、咏春拳。 文章深入浅出、语

    2024年02月04日
    浏览(41)
  • 领取的AWS亚马逊云服务器到期会扣费的问题解决办法。

    本篇文章主要讲解,领取的AWS亚马逊服务器到期后会持续扣费问题的解决办法。 作者:任聪聪 日期:2023年6月8日 关于aws服务器一年免费期限到期后扣费的问题,网络上的文章并不是很全,故此我通过个人的经验进行了如下的教程整理。 我将通过一些比较常见的问题对大家一

    2024年02月08日
    浏览(39)
  • 亚马逊S3解决跨域和权限问题

    S3对公网开放,解决权限问题 1、进入存储桶,点击权限,定位到“阻止公有访问(存储桶设置)”,全部不勾选 2、定位到“存储桶策略” 编辑更改内容 (公开) (可以是公有的) 3、解决跨域问题 定位到“跨源资源共享(CORS)”,编辑内容 相关亚马逊文档:亚马逊S3跨域配置

    2024年02月11日
    浏览(36)
  • 亚马逊云AWS,MINIO,阿里云OSS,华为云OBS主流文件系统STS服务端配置手册

    1,配置本地服务 Miniohost: minio访问地址 Username: minio admin账户名 Password: minio admin账户密码 创建配置成功后响应结果如下 2,利用mc创建访问用户 为local的minio服务创建一个用户派发STS : 账户:zhangsan ,密码 :zhangsan123 STSUsername: minio 派发STS用户名 STSPassword: minio派发STS用户密码 创

    2024年02月05日
    浏览(37)
  • 亚马逊云创建Aws EC2示例+用Xshell7连接登录Aws+设置允许使用root登录

    在学Linux,想着搞个服务器来玩玩,发现亚马逊云可以弄免费的服务器,跌跌撞撞才了不少坑,最后给弄好了,这里记录一下我的 创建Aws EC2示例+用Xshell7连接登录Aws+设置允许使用root登录 的整个过程,提供大家参考,也防止自己以后忘记怎么弄。 打开AWS EC2管理控制台,右上

    2024年01月16日
    浏览(32)
  • AWS 亚马逊云良好架构框架

    根据多年来AWS的专家们积累的经验,创建了这一份AWS良好架构框架,其中包含了以下五大支柱: 安全性(Security) 可靠性(Reliability) 性能效率(Performance Efficiency) 成本优化(Cost Optimisation) 卓越操作(Operational Excellence) 1、不需再猜测您的容量需求 2、以生产规模进行系

    2024年01月18日
    浏览(35)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包