S3の画像を圧縮してみた

AWS

こんにちは、せぃゆーです。

1年ぶりの投稿ですみません。

今回はS3に画像がアップロードされたときにlambdaを使って圧縮する処理をするための前段階のPythonでS3から画像を取得して圧縮する処理を書きました。

スポンサーリンク

前準備

S3にバケットを作って圧縮する画像をアップロードしてあること

注意

今回はここまで作業しませんが、S3に画像がPUTされたのを検知して、lambdaで画像圧縮をするときは圧縮した画像は画像がPUTされたバケットと別のバケットにPUTしてください

同じバケットにPUTすると「圧縮した画像のPUTを検知して再度lambdaが実行され圧縮してPUTして」の無限ループになり多額の請求が発生する可能性があります。

ソースコード

Pythonの実行環境はGoogleColaboratoryにしました。

普段はPHPerなのでPython独特の書き方に従ってないのは気にしないでください。

!pip install boto3 -q
import boto3
from PIL import Image
from io import BytesIO
import sys
import os

print(sys.version)

def image_compress(bytes_image_data, file_extension, quality=0):
    im = Image.open(bytes_image_data)
    im_io = BytesIO()
    im.save(im_io, file_extension, quality=COMPRESS_QUALITY)
    return im_io

# AWS関係
AWS_ACCESS_KEY_ID = 'hoge'
AWS_SECRET_ACCESS_KEY = 'piyo'
REGION_NAME = 'foo'
BUCKET_NAME = 'bar'
GET_KEY = '001/001.jpg'

# 圧縮のクオリティ
COMPRESS_QUALITIES = (10, 20, 30, 40, 50, 60, 70, 80, 90)

# S3クライアント作成
s3 = boto3.client('s3',
    aws_access_key_id=AWS_ACCESS_KEY_ID,
    aws_secret_access_key=AWS_SECRET_ACCESS_KEY,
    region_name=REGION_NAME
)
# オブジェクトデータを取得
obj = s3.get_object(Bucket=BUCKET_NAME, Key=GET_KEY)

# バイトデータを読み込み
bytes_image_data = BytesIO(obj['Body'].read())

file_paths = os.path.splitext(GET_KEY)
file_path = file_paths[0]
file_extension = file_paths[1][1:]

for i, COMPRESS_QUALITY in enumerate(COMPRESS_QUALITIES):
    im_io = image_compress(bytes_image_data, file_extension, COMPRESS_QUALITY)
    im_io.seek(0)
    PUT_KEY = f'{file_path}_compress_quality_{COMPRESS_QUALITY}.{file_extension}'
    s3.upload_fileobj(im_io, Bucket=BUCKET_NAME, Key=PUT_KEY)

圧縮結果

オリジナル画像と各圧縮クオリティごとのサイズです

比較用にオリジナル画像と圧縮クオリティを10にした画像も貼っておきます

オリジナル画像

圧縮クオリティ10の画像

まとめ

今回はPythonを使ってS3の画像を圧縮してみました。

Web上でみる分には圧縮クオリティ10にしてかなり圧縮しても問題ないように見えますね

次回はこの処理をベースにS3に画像がアップロードされたらlambdaで圧縮する処理をやりたいとおもいます。

コメント