[アップデート] Dynamic Image Transformation for Amazon CloudFront がアップデートされたのでスマートクロッピング拡張機能を通して初めて使ってみた
いわさです。
AWS には Dynamic Image Transformation for Amazon CloudFront(以下 DIT)というソリューションがあります。もともとは Serverless Image Handler という名前で提供されていたもので、今回触ってみて名前が変わっていたことを知りました[1]。
S3 に置いた元画像を CloudFront から配信するときに、URL のパラメータに応じてリサイズ・フォーマット変換(WebP など)・切り抜きをリアルタイムに行ってくれます。サムネイル生成やスマホ向けの最適化を、画像を何種類も用意しておかずに URL だけで済ませられます。
先日リリースされた v8.1.0 で、DIT に4つの新機能が追加されました。
- 拡張スマートクロッピング(顔に加えてラベル・テキスト・カスタムモデルで検出して切り抜き)
- デバイス種別に応じた自動最適化
- 画像変換プレイグラウンド(管理 UI で変換結果とメトリクスを確認できるページ)
- Lambda アーキテクチャと ECS アーキテクチャの機能差の解消
DevelopersIO で DIT(Serverless Image Handler)を取り上げた記事は見当たらなかったので、良い機会だと思い今回初めて触ってみました。
複数機能ありますが、今回はこのうちスマートクロッピングを試してみます。
先に書いておくと、管理 UI の設定までは一通りできたものの、用意した写真ではうまく切り抜けませんでした。
デプロイしてみる
DIT はソリューションページの Launch Wizard から数クリックでデプロイできます。今回もこれでいこうとしました。

ところが、Launch Wizard で選べるバージョンは 8.0.6 止まりで、8.1.0 はまだ配信されていませんでした(本日時点)。

CHANGELOG を見ると拡張スマートクロッピングは 8.1.0 の追加で、8.0.6 は依存パッケージのセキュリティ更新だけでした[2]。今回試したい機能が 8.0.6 には入っていません。
そこで今回は、GitHub の v8.1.0 タグのソースをクローンしてビルドし、生成された CloudFormation テンプレートと Lambda アセットを自分の S3 に置いてスタックを作成しました。
DIT を調べてみると、デプロイ方式に Lambda アーキテクチャと ECS アーキテクチャの2つがあるようです。Lambda 版は API Gateway + Lambda で画像を処理する構成、ECS 版は ALB + Fargate のコンテナで処理し、ポリシー管理用の管理 UI(Cognito 認証)が付く構成でした。拡張スマートクロッピングは ECS 版の方に入っていたので、今回は ECS アーキテクチャでデプロイしています。コンテナイメージは M1 Max の macOS で arm64 向けにビルドし、タスク定義も arm64 で作成しました。
ECS アーキテクチャの構成はこのようになっています。画像配信側(CloudFront から ALB・Fargate へ、そこから S3 や Rekognition を呼ぶ)と、ポリシーを管理する管理 UI 側(Cognito 認証の Web ポータルと Admin API)に分かれています。
デプロイすると、CloudFront のオリジンには Fargate の前段にある ALB が VPC オリジンとして設定されていました。

デプロイされた DIT から設定してみる
管理 UI のポータルにログインすると、左のメニューが Origins / Transformation Policies / Mappings / Playground の4つに分かれています。ECS アーキテクチャでは、この管理 UI でオリジン・ポリシー・マッピングを登録してからでないと画像を配信できません。
まず Origins で、元画像を置いた S3 バケットをオリジンとして登録します。

次に Transformation Policies でポリシーを作ります。
ポリシーに変換(Transformation)を追加していく形で、変換の一覧に Smart Crop があります。


Smart Crop を選ぶと、Simple と Advanced が選べます。
Simple は以前からある顔検出の切り抜きです。なので今回は Advanced の方を使いましょう。

v8.1.0 で追加されたのはこの Advanced です。顔だけでなくラベルやテキスト、自分で用意した Rekognition のカスタムモデルなど、複数の検出方法を指定できます。少なくとも1つの検出方法を指定すれば設定できました。

今回の検証画像は瓶なので、Labels に瓶を表す Bottle を指定しました(ラベル名は英語で指定します)。カンマ区切りで複数指定もできます。

Crop Settings では切り抜き後のアスペクト比・余白・切り抜きの中心をどこに置くか(Gravity)などを指定できます。
被写体が端に寄っている写真を縦長に切り抜きたいので、アスペクト比を 9:16 にしました。

Condition はリクエストヘッダの一致で変換を出し分ける任意設定なので、今回は空のままにしました。
最後にマッピングを作り、/smart/* というパスに先ほどのオリジンとポリシーを紐付けます。

なお、これらの設定変更は反映まで最大5分かかり、キャッシュ済みの画像は自動では更新されないという注意書きが各画面に出ていました。
リクエストした画像がどうなるか確認してみる
用意したのは横長の写真で、瓶が右端に寄っていて左側は木目のテーブルです。
この瓶は先日息子と小樽に観光に行ったのですが、その時に買ったやつです。アメジストみたいなやつが入ってる、よく観光地に売ってるやつです。

このまま縦長(9:16)に切り抜くと、中央を基準にした場合は瓶が範囲から外れてしまう構図です。ラベル検出で瓶の位置を拾ってくれれば、縦長でも瓶が残るのではと思って試しました。
マッピングしたパスにリクエストすると、変換後の画像が取得できます。
curl -o smart-bottle.jpg https://xxxxxxxx.cloudfront.net/smart/bottle.jpg
取得できたのは縦長(9:16)の画像です。ただ、瓶は入っておらず木目のテーブルだけになっていました。なんてこったい。
画像のほぼ中央を縦に切り出した形で、右端にあった瓶は範囲から外れています。

ECS のコンテナログを見ると、リクエストはマッピングで解決され、ラベル検出のポリシーは適用されていました。
{"component":"ImageRouter","operation":"request_start","path":"/smart/bottle.jpg","method":"GET"}
{"component":"MappingResolver","operation":"mapping_resolved","resolvedBy":"path","mappingType":"path","policyId":"..."}
ポリシーは適用されているのに切り抜きが瓶の位置にならないので、Rekognition が実際に何を検出しているのかも直接確認してみました。
元画像を detect-labels で解析すると、Bottle というラベルは付くものの、Instances(物体の位置を表すバウンディングボックス)が空でした。
{
"Name": "Bottle",
"Confidence": 55.77,
"Instances": []
}
ラベルは付くのに位置情報が入っていませんね。
完全に把握できていないのですが、おそらく拡張スマートクロッピングは検出した物体のバウンディングボックスを基準に切り抜き位置を決めているようです。位置情報が返らないとうまく処理できずに画像の中央を基準にした切り抜きになるっぽいです。
念のため、画像内でバウンディングボックスが得られるラベルが一つでもあるかも確認しましたが、min-confidence を下げても位置付きのインスタンスは一つもありませんでした。被写体(小さなガラス瓶)が小さく、背景の木目が画面の大半を占めているので、Rekognition が物体の位置を取れなかったのかなと思いました。
Lambda 版との違いを確認してみる
狙った切り抜きにはならなかったものの、Advanced の検出方法(ラベル・テキスト・カスタムモデル)が v8.1.0 で追加され、それが ECS アーキテクチャ側の機能であることは確認できました。
CHANGELOG の v8.1.0 でも、既存の顔検出に加えてラベル・テキスト・カスタムモデルでの切り抜きに対応した、と書かれています。
Enhanced Smart Cropping — expanded Amazon Rekognition integration to support smart-cropping across multiple detection methods. In addition to existing face detection, customers can now crop around Rekognition standard labels (e.g.
car, truck, van), retain text via Rekognition text detection, and train and supply their own Rekognition Custom Model for domain-specific detection.
Lambda アーキテクチャ側の画像処理のコードを見ると、スマートクロッピングは今も顔検出(顔のインデックスと余白の指定)だけで、ラベルやテキストの検出は入っていませんでした。
ラベル・テキスト・カスタムモデルの検出は ECS アーキテクチャ側のコードにあり、今回の管理 UI で設定した Advanced の検出方法もこちらです。
拡張スマートクロッピングを使いたい場合は、ECS アーキテクチャを選ぶことになりそうです。
さいごに
本日は DIT の拡張スマートクロッピングを ECS アーキテクチャで試してみました。
顔検出だけだったスマートクロッピングが、ラベル・テキスト・カスタムモデルでの検出に広がり、人物以外を主役にした切り抜きも設定できるようになりました。
うまく期待どおり画像は処理できなかったのですが、管理 UI で Advanced の検出方法を設定できることと、それが ECS アーキテクチャ側の機能であることは確認できました。
また、Launch Wizard がまだ 8.1.0 になっていなかったので、今回の機能を試すには GitHub からの自前ビルドが必要でした。ここはそのうち更新されるのかな。
プレイグラウンドやデバイス種別ごとの自動最適化など他の機能はまだ確認できていないので、それらも別途試してみたいと思います。
DIT CHANGELOG の v7.0.0 に改称の記載があります。GitHub リポジトリは今も
aws-solutions/serverless-image-handlerのままです ↩︎









