今回のエンジニアブログを担当する村田です。
前回は、Pythonを使ったAWS Lambdaでスケジュール化を試しました。
今回は、画像処理ライブラリである「Pillow」をAWS Lambdaで使いたいと思います。
Pillowとは?
Python Imaging Library (PIL)のforkプロジェクトで、
- ピクセル毎の操作
- マスキングと透明度の制御
- ぼかし、輪郭補正、スムージング、輪郭検出などの画像フィルタ
- シャープ化、明るさ補正、コントラスト補正、色補正などの画像の調整
- 画像へのテキストの追加
- その他いろいろ
といった様々な画像処理が可能なライブラリです。
実は前回使おうとしたのですが、このPillowというライブラリ、
インストール時に環境に合わせてビルドをするため、普通にMac上で環境を構築すると実行時にエラーが発生します。
Unable to import module 'lambda_function': /var/task/PIL/_imaging.so: invalid ELF header
AWS LambdaはEC2上で動いているようなものなので、今回はEC2(Amazon Linux AMI 2015.09)上で構築していきます。
環境構築
Amazon Linuxで構築したEC2に接続します。
まず、Pillowをビルドするのに必要なものをインストールします。
$ sudo yum install python-devel $ sudo yum install libtiff-devel libjpeg-devel libzip-devel freetype-devel \ lcms2-devel libwebp-devel tcl-devel tk-devel $ sudo yum install gcc
準備が整いましたら、AWS Lambda を実装する作業ディレクトリに移動し、setup.cfgを編集します。
Amazon Linuxに合わせた設定ですので、環境に合った内容を記載してください。
[install] install-purelib=$base/lib64/python
AWS LambdaにPillowをインストールします。
$ pip install Pillow -t .
インストールに成功すると、以下のようなディレクトリ構成になります。
<workdir> ├── PIL │ ├── BdfFontFile.py │ : │ : ├── Pillow-3.1.0.egg-info │ ├── PKG-INFO │ : │ : ├── lambda_function.py └── setup.cfg
では、lambda_function.pyを編集して、実装しましょう。
実装
今回の実装内容は以下の通りです。
- inputフォルダにPNG画像をPut
- Lambdaが起動しPutした画像からサムネイルを作成
- サムネイルをoutputフォルダに出力
2と3が、今回作成するLambdaが担当する処理です。
S3のBucket内は、以下のようにフォルダを作成します。
<Bucket> ├── input └── output
実装内容です。
from PIL import Image import boto3 import os import re s3 = boto3.client('s3') def lambda_handler(event, context): bucket = event['Records'][0]['s3']['bucket']['name'] key = event['Records'][0]['s3']['object']['key'] tmp = u'/tmp/' + os.path.basename(key) output = re.sub(r'^input/', u'output/', key) try: s3.download_file(Bucket=bucket, Key=key, Filename=tmp) img = Image.open(tmp, 'r') img.thumbnail((80, 80), Image.ANTIALIAS) img.save(tmp, 'PNG') s3.upload_file(Filename=tmp, Bucket=bucket, Key=output) return except Exception as e: print(e) raise e
11行目で、/tmp/へのパスを生成しておりますが、今回のプログラムでは、S3上にアップされたPNG画像を /tmp/ 配下に一旦ダウンロード(14行目)します。
Lambdaから/tmp/へのアクセスが可能で、/tmp/の容量は 500MB となっております。
16行目で 80x80 のサムネイルを作成します。
18行目で 作成したサムネイルを output フォルダにアップします。
今回は、以下のようにevent sourcesを設定することで、inputにPutしたpng拡張子にしか反応しないようにしました。
まとめ
Pillowが扱えるということで、複雑な画像処理がAWS Lambda上で実現できるようになりました。
Pillowに限らずビルドを必要とするライブラリをAWS Lambda上で扱えるというのは、Pythonで実装するAWS Lambdaの可能性がより広がります。
ますますPythonで実装するAWS Lambdaが好きになりました。