こんにちは、せぃゆーです。
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で圧縮する処理をやりたいとおもいます。
コメント