画像処理をAWS LambdaのPythonで!

Preview:

Citation preview

画像処理を AWS LambdaのPythonで!

JAWS-UG Meetup in AWS Cloud Roadshow 名古屋

ワンダープラネット株式会社 取締役 CTO 村田知常

自己紹介• 村田 知常(むらた ともつね)  tomotsune.murata

• ワンダープラネット株式会社 取締役 CTO

• 好きな言語 Swift

• 好きなAWS    Amazon S3

  ワンダープラネット株式会社• 2012年9月3日 設立

• iOS/Android向けフルネイティブのソーシャルゲームを出してます

• AWSには大変お世話になってます! 本日、ver.1.1.6を配信!本日、ver.1.1.6を配信!

re:Invent2015で来ました \(^O^)/

Lambda

+

• サーバーサイドのメイン言語

• MayaのPythonスクリプティング

• ちょっとしたコマンドラインツール

+

早速、試しました! (-_☆)キラーン

• Pythonで実装

• RSSフィードを定期的に取得→ 新機能 スケジュール化 の検証

• RSSフィードの解析に「feedpaser」 → 外部ライブラリの利用

• CloudWatchのLogsに出力→ printで手抜き

本当に試したかったのは これではなかった…

S3に画像をアップしたら Pythonライブラリを使って

画像を加工したい ※ 外部サービスは使わず

ブログアップ日に 間に合わなかった…

画像処理ライブラリ 使おうとした

Python Imaging Library (PIL)のforkプロジェクト•ピクセル毎の操作

• マスキングと透明度の制御

• ぼかし、輪郭補正、スムージング、輪郭検出などの画像フィルタ

• シャープ化、明るさ補正、コントラスト補正、色補正などの画像の調整

• 画像へのテキストの追加

• その他いろいろ

Unable to import module 'lambda_function': /var/task/PIL/_imaging.so: invalid ELF header

普通にMac上で実装したものを Lambdaで実行すると…

Pillowインストール時に環境に合わせて 一部ライブラリをビルドしているMac向けにビルドしたものは Linux上では動かないよ

$ 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

EC2(Amazon Linux AMI 2015.09)上で構築必要なライブラリをインストール

作業ディレクトリに移動$ vim setup.cfg

[install] install-purelib=$base/lib64/python

$ pip install Pillow -t .

Pillowのドキュメントに沿ってインストール

ビルドに必要 (gcc無いのね…)

<workdir> ├── PIL │   ├── BdfFontFile.py │   : │   : ├── Pillow-3.0.0.egg-info │   ├── PKG-INFO │   : │   : ├── lambda_function.py ← このファイルを作成し実装 └── setup.cfg

完成するとこんな感じ

Macで作ると Pillow-3.0.0.dist-info

準備完了 \(^O^)/

EC2(Amazon Linux AMI 2015.09)上で構築

Lambda functionの実装

• inputフォルダにPNG画像をPut

• Lambdaを起動しサムネイルを作成

• サムネイルをoutputフォルダに出力

Lambda functionの実装

オリジナル画像

80x80画像

Lambdaで 画像を加工

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'] print u'Bucket=' + bucket print u'key=' + 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

Lambda functionの実装

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'] print u'Bucket=' + bucket print u'key=' + 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

Lambda functionの実装

Bucketから ファイルを取得 /tmp/下に保存

Lambdaから /tmp/はアクセス可能 容量は500MB

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'] print u'Bucket=' + bucket print u'key=' + 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

Lambda functionの実装

80 x 80 サムネイルを作成

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'] print u'Bucket=' + bucket print u'key=' + 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

Lambda functionの実装

output/に ファイルをアップロード

時間があったら デモ

まとめ

• Pillowを使えば色々と凝った画像処理が可能

• ビルドを必要とするライブラリをAWS Lambdaで使うノウハウを習得

• AWS LambdaをPythonで実装できる!

• これで開発・運用をサポートするツール作成が捗る

ご清聴ありがとうございました

Recommended