エンジニア

画像処理ライブラリ「Pillow」をAWS Lambdaで使ってみる

投稿日:2016年2月2日 更新日:

今回のエンジニアブログを担当する村田です。

前回は、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を編集して、実装しましょう。

実装

今回の実装内容は以下の通りです。

  1. inputフォルダにPNG画像をPut
  2. Lambdaが起動しPutした画像からサムネイルを作成
  3. サムネイルを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拡張子にしか反応しないようにしました。
BucketSetting

まとめ

Pillowが扱えるということで、複雑な画像処理がAWS Lambda上で実現できるようになりました。
Pillowに限らずビルドを必要とするライブラリをAWS Lambda上で扱えるというのは、Pythonで実装するAWS Lambdaの可能性がより広がります。

ますますPythonで実装するAWS Lambdaが好きになりました。

採用情報

ワンダープラネットでは、一緒に働く仲間を幅広い職種で募集しております。

-エンジニア
-,

© WonderPlanet Inc.