Cloudflare Workers AI 使ってみた「画像インペインティング編」
はじめに
こんにちは、いけがわです。
今回は画像の一部を変更できる Stable Diffusion Inpainting モデル(stable-diffusion-v1-5-inpainting
)を使用してみました。
インペインティングは、画像内の特定部分に対して指示した変換(たとえば「犬をライオンに変える」など)を行う技術で、マスク画像を使って変換対象を指定する点が特徴です。
前提条件
この記事を進めるにあたり、以下の準備が必要です。
-
Cloudflare アカウント
Workers AI の利用に必須。対象のモデルが有効になっているか確認してください。 -
Node.js / Bun 開発環境
今回は軽量な Hono フレームワークと Bun を使ってサーバーを構築します。 -
ローカル画像とマスク画像
インペインティングでは、入力画像とその変更箇所を示すマスク画像が必要です。なければ、デフォルト画像(Cloudflare 公式サンプル)を使用します。
実装手順
1. 環境のセットアップ
まず、Hono プロジェクトを作成します。
bun create hono@latest image-inpainting-app
cd image-inpainting-app
2. APIリクエストの実装
使用するモデルは stable-diffusion-v1-5-inpainting
です。以下は、画像インペインティング用のエンドポイント実装例です。
import { Hono } from "hono";
import { existsSync, readFileSync } from "fs";
import { saveImage, arrayBufferToBase64 } from "./utils";
import { makeApiRequest } from "./usecase";
const app = new Hono();
app.post("/inpaint", async (c) => {
try {
const { prompt, image_b64, mask_b64 } = await c.req.json();
if (!prompt) {
return c.json({ success: false, error: "Prompt is required" }, 400);
}
// ローカルの画像パス
const localImagePath = "./images/input.png";
const localMaskPath = "./images/mask.png";
// 画像とマスクの取得
const imageBase64 =
image_b64 ||
(existsSync(localImagePath)
? readFileSync(localImagePath).toString("base64")
: await fetch("https://pub-1fb693cb11cc46b2b2f656f51e015a2c.r2.dev/dog.png")
.then((res) => res.arrayBuffer())
.then((buffer) => arrayBufferToBase64(buffer)));
const maskBase64 =
mask_b64 ||
(existsSync(localMaskPath)
? readFileSync(localMaskPath).toString("base64")
: await fetch("https://pub-1fb693cb11cc46b2b2f656f51e015a2c.r2.dev/dog-mask.png")
.then((res) => res.arrayBuffer())
.then((buffer) => arrayBufferToBase64(buffer)));
// Cloudflare API へリクエスト
const inputs = { prompt, image: imageBase64, mask: maskBase64 };
const response = await makeApiRequest({
endpoint: "/ai/run/@cf/runwayml/stable-diffusion-v1-5-inpainting",
data: JSON.stringify(inputs),
contentType: "application/json",
});
// 画像を保存
const imageData = new Uint8Array(await response.arrayBuffer());
const filename = `inpainted_image_${Date.now()}.png`;
const filePath = await saveImage(filename, imageData);
return c.json({ success: true, path: filePath });
} catch (error) {
return c.json(
{ success: false, error: error instanceof Error ? error.message : "Unknown error" },
400
);
}
});
Bun.serve({ fetch: app.fetch, port: 8080 });
export default app;
動作確認
1. サーバーの起動
bun run index.ts
2. インペインティングのリクエスト
curl -X POST http://localhost:8080/inpaint \
-H "Content-Type: application/json" \
-d '{"prompt": "Change the dog into a lion"}'
結果の比較
入力画像 | マスク画像 | 生成結果 |
---|---|---|
![]() |
![]() |
![]() |
生成された画像がプロンプトで指定した「ライオン」のように見えない結果となりました。Stable Diffusion Inpainting モデルには、生成結果を調整するための以下のオプション・パラメータが用意されています。
生成された画像がプロンプトで指定した「ライオン」のようには見えますが、鮮明に表現はされない結果となりました。
Stable Diffusion Inpainting モデルには、生成結果を調整するための以下のオプションが用意されています。
- prompt: 生成したい画像の説明をテキストで指定。
- negative_prompt: 生成画像から除外したい要素をテキストで指定。
- height: 画像の高さ(最小 256px、最大 2048px)。
- width: 画像の幅(最小 256px、最大 2048px)。
- image: img2img タスク用の入力画像データ(8 ビットの整数配列)。
- image_b64: img2img タスク用の Base64 エンコードされた画像。
- mask: インペインティング用のマスク画像データ(8 ビットの整数配列)。
- num_steps: 拡散ステップの数(最大 20)。値を増やすと品質向上、処理時間も長くなる。
- strength: img2img タスクでの変換強度(0 ~ 1)。低い値にすると元画像に近くなる。
- guidance: 生成画像がプロンプトにどれだけ忠実であるかを制御(デフォルト 7.5)。高い値にするとプロンプトにより沿った画像になる。
- seed: 画像生成の再現性を持たせるためのランダムシード。
これらのオプションを適切に調整することで、生成結果の精度を高めることが期待できます。
今後、これらのパラメータを活用して、よりプロンプトに沿った画像生成を目指していきたいと考えています。
詳細については、公式ドキュメントをご覧ください。
まとめ
今回の検証では、Cloudflare Workers AI を活用した画像インペインティングの実装方法を紹介しました。今後は、より高度なプロンプト設計や前処理を工夫することで、さらに高品質な画像編集を試みたいと考えています。
お知らせ
toraco株式会社では、エンジニア向けコミュニティを 2024年11月1日 より開始しました。
Discord サーバーでは、
- もくもく会・作業ラジオ・雑談部屋
- オフラインイベントの案内
- 副業や案件の紹介
- フロントエンド・生成AI技術の情報共有
など、さまざまな活動を行っています!
ぜひ、こちらからご参加ください。
Discussion