Communitygithub.com

firefly-expand-fill

Adobe Firefly の Generative Expand と Generative Fill の2つのAPIを使用して、既存画像のキャンバス拡張、領域修正、背景置換などを実行するためのスキルです。マスク戦略、配置とアスペクト比の制御、クリーンな拡張とインペインティングのためのプロンプトパターンをカバーします。

firefly-expand-fill とは?

このスキルは、Adobe Firefly Services の Generative Expand (v3/images/expand) と Generative Fill (v3/images/fill) の2つのAPIを、プロダクション品質で使い分けるための知識と実装パターンを提供します。Expand はキャンバスを拡大して新しい領域にコンテンツを生成し、アスペクト比の変更やアウトペインティングに適しています。一方、Fill はマスクで指定した既存領域を修正・置換し、背景の差し替えやオブジェクト削除などのインペインティングに使用します。スキルは、マスク生成戦略(Photoshop API の被写体検出、プログラム的生成など)、配置制御、プロンプト設計、そして Expand と Fill を組み合わせたパイプライン(例:キーアートの背景拡張→テキスト除去)を、実際のエンタープライズ開発(FDE)での知見に基づいて解説しています。高スループットのワークフローにおける並列処理やレート制限への対応についても触れています。

対応✓Claude Code~Codex CLI~Cursor
npx skills add Focus-GTS/firefly-services-skills

お気に入りのAIに質問する

このエージェントスキルを事前に読み込んだ状態で新しいチャットを開きます。

ドキュメント

Firefly Generative Expand & Fill

既存画像を変更するための、関連はあるが異なる2つのAPIについて説明します。Expand はキャンバスを拡大し、新しい領域に新しいコンテンツを生成します。Fill はマスクでガイドされた、既存のキャンバス内の領域を変更または置換します。適切な方を選ぶことが作業の半分であり、残りはマスクの品質です。

このスキルを使用するタイミング

以下の場合にこのスキルを使用します:

  • ユーザーが画像のキャンバスを任意の方向に拡張したい場合
  • ユーザーが画像の領域(背景、オブジェクト、テキスト領域)を置換または変更したい場合
  • キャンペーンで単一のソースアセットから複数のアスペクト比が必要な場合
  • クリエイティブチームが画像から不要なオブジェクトを削除したい場合
  • ユーザーがインペインティング、アウトペインティング、拡張、または塗りつぶしについて言及した場合

以下の場合にはこのスキルを使用しないでください:

  • ユーザーが完全に新しい画像を希望する場合 — firefly-generate-image-v3-async を使用
  • ユーザーが既存画像のスタイルバリエーションを希望する場合 — firefly-generate-similar を使用
  • 変換が純粋なラスター編集(シャープネス、色補正)である場合 — Lightroom API を使用

Expand と Fill の比較 — 判断表

ニーズエンドポイント
キャンバスを拡大し、新しい領域にコンテンツを生成Expand
画像のアスペクト比を変更 (1:1 → 16:9)Expand
オブジェクトを削除し、その領域をパッチFill
被写体を維持したまま背景を置換背景をカバーするマスクで Fill
特定の領域(空、地面、人のシャツ)を置換Fill
損傷した領域や不要な領域をインペイントFill
アウトペイント(古典的なAIアート「フレームの外を生成」)Expand

要約すると:キャンバスが大きくなる = Expand。キャンバスはそのまま = Fill。

Generative Expand

ステップ1 — Expand ジョブの送信

curl --silent -X POST 'https://firefly-api.adobe.io/v3/images/expand' \
  -H "Authorization: Bearer $FIREFLY_SERVICES_ACCESS_TOKEN" \
  -H "X-Api-Key: $FIREFLY_SERVICES_CLIENT_ID" \
  -H 'Content-Type: application/json' \
  -d '{
    "image": {"source": {"uploadId": "$SOURCE_UPLOAD_ID"}},
    "size": {"width": 2304, "height": 1280},
    "prompt": "a sweeping desert landscape continuing into the distance",
    "placement": {
      "alignment": {"horizontal": "center", "vertical": "center"}
    },
    "numVariations": 2
  }'

非同期ジョブパターン(jobId、statusUrl、cancelUrl)を返します — firefly-generate-image-v3-async と同じ方法でポーリングします。

placement フィールド

placement は、元の画像が 新しい(より大きな)キャンバス内のどこに配置されるかを制御します:

"placement": {
  "alignment": {"horizontal": "center", "vertical": "center"},
  "inset": {"left": 0, "top": 0, "right": 0, "bottom": 0}
}
配置効果
center, center元の画像が中央に、すべての辺に均等に拡張
left, center元の画像が左に、右側に拡張
right, top元の画像が右上に、下と左に拡張

細かいピクセル制御には inset を使用します。典型的なパターン:元の画像を中央に、均等に拡張します。ソーシャルメディアのバリエーション(ランドスケープ→ポートレート)の場合は、被写体がセーフエリアに収まるように元の画像を中央からオフセットして配置します。

Expand の prompt フィールド

プロンプトは、新しい(拡張された)領域に何を含めるべきかを説明します。元の画像はそのままです。例:

元の画像プロンプト結果
人物のポートレート"the rest of their body in a business suit"元の頭部 + 新しい体
白い背景の製品"a kitchen counter with morning light"シーン内の製品
風景のクローズアップ"a vast sky with scattered clouds above"シーンが上に続く

prompt を空のままにすると、Firefly が既存のコンテンツをスタイル的に拡張します(クロップ/リクロップワークフローで一般的)。

アスペクト比レシピ

一般的なプロダクションユースケース:

元のサイズ変換後sizeplacement.alignment
1024×1024 (1:1)1408×768 (16:9 ランドスケープ)width 1408, height 768center, center
1024×1024 (1:1)768×1408 (9:16 ポートレート)width 768, height 1408center, top (顔の下部)
1408×768 (キーアート)2304×1280 (シネマティック)width 2304, height 1280center, center
1024×1024 (スクエア)1024×1792 (ストーリー ポートレート)width 1024, height 1792center, top

Generative Fill

ステップ1 — マスクの準備

Fill には、Firefly にどの領域を変更するかを指示するマスクが必要です。白ピクセル = この領域を塗りつぶす。黒ピクセル = そのまま保持。グレースケール = ソフトブレンド。

マスクはソース画像と同じ寸法でなければなりません。マスクはクライアント側(画像エディター、Photoshop API、または sharp / pillow を使用したプログラム)で生成し、ストレージ参照としてアップロードします。

# マスクのアップロード
MASK_UPLOAD_ID=$(curl --silent -X POST 'https://firefly-api.adobe.io/v2/storage/image' \
  -H "Authorization: Bearer $FIREFLY_SERVICES_ACCESS_TOKEN" \
  -H "X-API-Key: $FIREFLY_SERVICES_CLIENT_ID" \
  -H "Content-Type: image/png" \
  --data-binary "@./mask.png" \
  | jq -r '.images[0].id')

ステップ2 — Fill ジョブの送信

curl --silent -X POST 'https://firefly-api.adobe.io/v3/images/fill' \
  -H "Authorization: Bearer $FIREFLY_SERVICES_ACCESS_TOKEN" \
  -H "X-Api-Key: $FIREFLY_SERVICES_CLIENT_ID" \
  -H 'Content-Type: application/json' \
  -d '{
    "image": {
      "source": {"uploadId": "$SOURCE_UPLOAD_ID"},
      "mask": {"source": {"uploadId": "$MASK_UPLOAD_ID"}}
    },
    "prompt": "a modern minimalist living room background",
    "numVariations": 2
  }'

非同期ジョブパターンを返します — 完了するまでポーリングします。

Fill の prompt フィールド

プロンプトは、マスクされた領域に何を表示するかを説明します。マスクされていない領域はそのままです。

マスクの対象プロンプト結果
製品ショットの背景"marble kitchen counter"製品はそのまま、新しい背景
不要な人物"empty park bench"人物が削除され、ベンチが領域を埋める
ラベル領域"minimal white space"ラベルがなくなり、領域がクリーンに
車両の色領域"matte red paint"車両が赤に

マスク生成戦略

戦略ツールいつ使用するか
手動マスクPhotoshop、画像エディター単発のクリエイティブ作業
プログラムによるマスクsharp、pillow幾何学的な領域(上半分、左3分の1)
被写体検出Photoshop API select_subject またはカスタムセグメンテーション背景の置換、被写体の分離
カラーキーマスクsharp しきい値処理特定の色の領域の置換
AI セグメンテーションSAM (Segment Anything)、Mediapipeプロダクションセグメンテーションパイプライン

高スループットワークフロー(毎日数百のキーアートアセットの背景拡張)の場合、マスクは被写体検出からプログラム的に生成されます — 手動では決してありません。

パイプラインでの Expand と Fill の組み合わせ

一般的なプロダクションパイプライン:

ソースキーアート (1408×768)
  ↓ Expand (2304×1280 へ、シーンを拡張するプロンプト)
拡張された画像
  ↓ Fill (マスクはテキスト領域をカバー、プロンプト: "clean background")
クリーンなシネマティックバージョン
  ↓ Photoshop API アクションの適用 (テキストオーバーレイ、レイヤーコンポジション)
最終アセット

これは、凝縮された標準的なキーアート生成パターンです。各ステージは非同期ジョブです。パイプラインはキューで管理されます(firefly-services-rate-limits を参照)。

プロダクションパターン

パターン: 単一ソースからのマルチアスペクト生成

1つのスクエアキーアートから、ランドスケープ + ポートレート + ストーリーフォーマットを生成します:

const aspects = [
  { name: 'landscape-16-9', size: { width: 1408, height: 768 }, alignment: { horizontal: 'center', vertical: 'center' } },
  { name: 'portrait-9-16', size: { width: 768, height: 1408 }, alignment: { horizontal: 'center', vertical: 'top' } },
  { name: 'story-9-16', size: { width: 1024, height: 1792 }, alignment: { horizontal: 'center', vertical: 'top' } },
];

const jobs = await Promise.all(
  aspects.map(a => submitExpand({
    sourceUploadId: SOURCE_ID,
    size: a.size,
    placement: { alignment: a.alignment },
    prompt: 'continue the scene naturally',
    numVariations: 2,
  })),
);

3つの送信で、並行して約6つの出力が得られます。それぞれをアスペクトタグとともに永続化し、下流のクリエイティブチームに渡します。

パターン: スケールでの背景置換

ブランドキャンペーンクリエイター向けの背景スワップの場合:

ソース画像
  ↓ Photoshop API: select_subject → マスク (被写体 白, 背景 黒)
  ↓ マスクを反転 (被写体 黒, 背景 白) — Sharp/Pillow
反転したマスクで Fill リクエスト
  ↓ プロンプト: "<brand-aligned background>"
出力: 被写体はそのまま、新しい背景

反転ステップは重要です — Photoshop の select_subject は被写体マスクを提供しますが、背景置換にはその逆が必要です。

検証

Expand/Fill パイプラインは、以下の場合にプロダクション対応となります:

  1. Expand と Fill の判断がユースケースごとに文書化されている
  2. マスク生成が自動化されており、手動ではない(50を超えるボリュームの場合)
  3. マスクが送信前に正しい寸法と適切な極性であることが検証されている
  4. 出力が成功とマークされる前に、ソースと視覚的に検査されている
  5. マルチアスペクトパイプラインが逐次ではなく並行で送信されている
  6. placement の決定がブランドのセーフエリアガイドラインに沿っている

トラブルシューティングとエッジケース

  • Expand 出力で元のコンテンツと新しいコンテンツの間に継ぎ目が見える: 元の画像に異常な色や粒状感がある可能性があります。シードを変更して再生成するか、ソースの品質を説明するプロンプトで Expand を試してみてください。
  • Fill プロンプトが無視される: マスクが反転している可能性が高いです(白=保持、黒=塗りつぶし のはずが逆になっている)。マスクの極性を再確認してください。
  • Fill 出力がマスクの外側ににじむ: マスクのエッジが柔らかすぎます(ガウシアンブラーが強すぎる)。マスクのエッジをシャープにするか、バイナリマスクを使用してください。
  • Expand で被写体の配置が予期せず変更される: placement.alignment を明示的に設定してください。デフォルトでは被写体が移動する可能性があります。
  • マスクが大きすぎる (>8MB): マスクを圧縮してください。限定パレットのシングルチャンネルグレースケール PNG は通常、適切に圧縮されます。
  • 極端なアスペクト比への Expand が不自然に見える: Expand を2ステップで行ってください:元の → 中間 → 最終。各ステップでの変化を小さくします。
  • Fill で被写体が完全に削除される: マスクが被写体に重なっています。マスクを背景のみに絞ってください。

他のスキルとの連携

  • firefly-services-storage-refs — マスク + ソースのアップロード
  • firefly-generate-image-v3-async — 同じ非同期パターン
  • photoshop-api-actions — 自動マスク生成用 (select_subject)
  • firefly-services-rate-limits — バッチパイプライン用

参考情報

関連スキル