0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

LambdaでPillowとnumpyを使った画像分割にハマった話(Layer + Dockerで解決)

0
Last updated at Posted at 2026-03-22

はじめに

LINEスタンプ用の画像を自動生成して、それをまとめてZIPでダウンロードできる仕組みを作りました。

構成はシンプルです。

・S3に画像を保存
・Lambdaで取得
・4x4に分割
・ZIPにまとめて再びS3へ

ただし…

Pillowとnumpyでかなりハマりました。
理由は Appleシリコン → Lambda(arm64) という環境差です。

👉 この記事はその記録です。

前回との違い(別の解決アプローチ)

前回は、PillowやnumpyをそのままLambdaに含める形で対応していましたが、
今回は構成を見直し、Layerを使った方法に変更しました。

具体的には、

・依存ライブラリ(Pillow、numpy)はLayerに分離
・Lambda本体は処理ロジックのみの軽量構成
・Dockerを使ってLambda環境に合わせたビルドを実施

という形にしています。

なぜこの方法に変えたか

前回の方法では、以下の課題がありました。

・デプロイサイズが大きくなりやすい
・ビルド環境によっては動かないことがある
・修正のたびにデプロイが重い

今回の方法にすることで、

・デプロイが高速化
・環境依存の問題を回避
・構成がシンプルに分離

といったメリットがありました。

やってみて感じたこと

最初はLayerやDockerの設定に少し手間取りましたが、
一度構成ができてしまえば、その後の開発はかなり楽になりました。

特に、デプロイ速度が大きく改善されたのは体感としても分かりやすく、
開発のストレスがかなり減りました。

やりたかったこと

rawフォルダにある画像を
Lambdaで取得して
Pillowで分割し
ZIPにまとめて
S3に保存する

最初の問題:Pillowが動かない

Lambdaで以下のエラーが出ました。

No module named ‘PIL’

解決しようとしてハマる

pip install pillow numpy をしてデプロイすると、

サイズ制限(250MB)に引っかかります。

Dockerでビルド

Dockerでビルドする際は、前回の記事を参考にしました。

特に、Lambda環境に合わせたライブラリのビルド方法について非常に参考になりました。

Lambda用の環境でPillowとnumpyをビルドするためにDockerを使いました。

ただしここでも問題が発生します。

numpyのビルドでコンパイラが見つからず失敗します。

解決

–only-binary=:all: を指定して、ホイールを強制使用することで解決しました。

次の問題:Layerのサイズ制限

Function code combined with layers exceeds 262MB

というエラーが発生しました。

解決:構成を分離

Lambda本体と依存ライブラリを分けました。

Lambda本体は軽量にし、
PillowとnumpyはLayerに分離します。

さらにハマる:Layerが効かない

No module named ‘PIL’

というエラーが再び発生。

原因はzipの構造でした。

正しいLayer構造

layer.zip の中に python フォルダが必要です。

pythonフォルダの中にPILやnumpyが入っている構造にします。

さらにハマる:importできない

NameError: name ‘Image’ is not defined

というエラーが発生。

解決

・sys.pathに /opt/python を追加
・from PIL import Image を正しく書く
・必要に応じて型ヒントの評価を遅延させる

完成構成

S3(raw)
→ Lambda(pack)
→ Layer(Pillow / numpy)
→ ZIP生成
→ S3(zips)

結果

original

1024x1024の画像を20分割できるようになりました。

ZIPも正常に生成されました。
デプロイも高速化されました。

学び

Layerはpythonフォルダ構造が重要
numpyはビルドが難しい
Dockerは非常に有効
Lambdaは軽量に保つべき

おわりに

最初は「なんで動かないの?」という状態でしたが、
試行錯誤を重ねて、最終的には画像を分割しZIPとして出力できるようになりました。

環境や構成によっては同じようにハマることもあると思います。
この記事が、どこかで困っている方のヒントになれば嬉しいです。

追記

もう一度layer.zip作ろうと思ったらすっかり忘れてしまっていたのでメモ

localで以下のフォルダを作る

mkdir -p layer/python
cd layer

dockerでビルド

docker run --rm -v "$PWD":/var/task public.ecr.aws/lambda/python:3.11
pip install pillow numpy -t python --only-binary=:all:

ビルド完了後にpythonフォルダをzip化

zip -r layer.zip python

lambdaにアップロードで完了

PILを使っているpythonファイルの上に以下を追加
import sys
sys.path.insert(0, "/opt/python")

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?